给你1元2元5元的硬币的数量,求最小不能组成的钱数是多少?
#include <bits/stdc++.h>
using namespace std;
int c1[100000],c2[100000];
int num[4],maxn=0;
int value[4]={1,2,5};
int main(){
while(scanf("%d%d%d",&num[0],&num[1],&num[2])){
for(int i=0;i<3;++i) maxn+=value[i]*num[i];
if(maxn==0)break;
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
c1[0]=1;//只对1初始化就可以了
//int ma=0;
//maxn=0;
for(int i=0;i<3;++i){ //觉得这三层循环非常重要,分别处理的是 第一个多项式 第一个和第二个多项式相乘 在和最后一个多项式相乘得到的结果,开始的时候没有注意到这一点,在初始化上就直接把对第一个多项式给处理了。
//ma=maxn+num[i]*value[i];
for(int j=0;j<=maxn;++j)
for(int k=0;k<=num[i];++k)
c2[j+k*value[i]]+=c1[j];
for(int j=0;j<=maxn;++j)
{
c1[j]=c2[j];
c2[j]=0;
}
//maxn=ma;
}
for(int i=0;i<=maxn+1;++i)
{
if(!c1[i]){printf("%d\n",i);break;}
}
maxn=0;
}
return 0;
}
/*
还有一个减少复杂度的地方就是注释掉的那四行代码了。
*/
For example, assume N is 4, we can find:
4 = 4;
4 = 3 + 1;
4 = 2 + 2;
4 = 2 + 1 + 1;
4 = 1 + 1 + 1 + 1;
so the result is 5 when N is 4. Note that "4 = 3 + 1" and "4 = 1 + 3" is the same in this problem. Now, you do it!"
用生成函数比用dp整数拆分减少了很多思维
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000;
int c1[maxn];
int c2[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
//c1[0]=1;
for(int i=0;i<=0;++i)
c1[i]=1,c2[i]=0;
// for(int i=1;i<n;++i)只对n=0处理就好了
// c1[i]=1,c2[i]=0;
for(int i=1;i<=n;++i)
{
for(int j=0;j<=n;++j)
{
for(int k=0;(k+j)<=n;k+=i)
{c2[j+k]+=c1[j];
}
}
for(int j=0;j<=n;++j)
c1[j]=c2[j],c2[j]=0;
}
printf("%d\n",c1[n]);
}
return 0;
}