#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
纯自己手打的
时不时发表博客分享自己的学习经验,觉得有帮助的可以关注一下
如果有什么问题欢迎指正
动态规划思路如果有什么问题可以提出