0
点赞
收藏
分享

微信扫一扫

蓝桥杯第十届C++省赛B组 题目D 数的分解(dfs附带详细思路和详细动态规划思路看不懂你捶我)

沈芏 2022-03-30 阅读 3

#include<iostream>
using namespace std;
#include<string>
#include<set>
typedef long long ll;

//整数划分问题,交换次序只算一次划分
//思路:假设求7的三划分
//7的划分有(1,6)(2,5)(3,4)(4,3)(5,2)(6,1) 形式为(x,y)
//其中x为被划分出来的数字,y为剩下的数字
//去重思路:要求x<=y即可  说人话就是 前面一个数字必须小于等于后面的数字
//去重后7的二划分就剩下(1,6)(2,5)(3,4)
//要求7的三划分就只需要再把y二划分即可
//再二划分6之后有(1,1,5)(1,2,4)(1,3,3)(1,4,2)(1,5,1)
//再二划分5之后有(2,1,4)(2,2,3)(2,3,2)(2,4,1)
//但是前面要求了x<=y 因此去掉划分中的不符合条件的划分数 
//比如(1,4,2)和(2,3,2)

//动态规划思路:
//int dp[2000][4][2000];  
//dp数组各个维度下标对应Solve函数的参数
//初始化dp数组为0
//Solve函数返回值 修改为 返回划分次数
//Solve函数res++ 修改为 return dp[num][length][pre]=1;
//Solve函数的递归式 修改为 dp[num][length][pre]+=Solve(num-i,length-1,i);
//Solve函数新增条件 if(dp[num][length][pre] > 0 ) return dp[num][length][pre];

ll res=0;

//判断是否包含数字2或4的函数
bool Contain2or4(int num)
{
	while(num!=0)
	{
		if(num%10==2 || num%10==4)	return true;
		num/=10;
	}
	return false;
}

//参数为 剩余数字 划分次数 上次被划分出来的数字 
void Solve(int num,int length,int pre)
{	
	if(Contain2or4(pre))
		return;
	else if(length==1 && Contain2or4(num))
		return;
	else if(length==1)
	{
		res++;
		return;
	}
	for(int i=pre==0?1:pre ; i<=num/2 ; i++)
	{
        //这里可以直接得到三个划分数,因此可以直接在这里判断三个数是否相等
		if(length==2 && (pre==num-i || pre==i || num-i==i ) )    
			continue;
		Solve(num-i,length-1,i);
	}
}

int main()
{
	Solve(2019,3,0);
	cout<<res;
	return 0;
}

 

答案:40785

纯自己手打的

时不时发表博客分享自己的学习经验,觉得有帮助的可以关注一下

如果有什么问题欢迎指正

动态规划思路如果有什么问题可以提出

举报

相关推荐

0 条评论