//题意:给你面值是1,2,5的硬币的数量,要你求由这些硬币不能组成的最小的金额。。
下面给出3种方法;
//方法1:很明显母函数
//我这里一步一步的求。。
//下面是我的一点理解。。如果叫你写由面值1,2,5的硬币所组成的金额的母函数
//Y=(1+x^2+x^3+x^4…+x^n1*1)*(1+x^2+x^4+x^6…x^n2*2)*(1+x^5+x^10+…x^n3*5)
//这里要理解。。配合HDU 1085来理解。。
#include <iostream>
#include <stdio.h>
using namespace std;
int c1[10000],c2[10000];
int main()
{
int i,j,k;
int a,b,c;
int sum=0;
while(scanf("%d%d%d",&a,&b,&c)!=EOF)
{
if(a==0&&b==0&&c==0)break;
sum=a+b*2+c*5;
for(i=0;i<sum;i++)
{
c1[i]=0;
c2[i]=0;
}
for(i=0;i<=a;i++)//第一个表达式。。(1+x^2+x^3+x^4…+x^n1*1)都取一个。。
c1[i]=1;
for(i=0;i<=a;i++)//先是面值1,和面值2,的硬币的母函数,。。就是第一个表达式乘第二个表达式;i控制的是第一个表达式指数。。j是第二个表达式的指数。。
for(j=0;j<=b*2;j+=2)//j+=2..就是上面的Y=()()()的第一式子。。这样比较好理解
c2[i+j]+=c1[i];//这步就是把指数相同的合并在一起,也就是把指数相同的系数相加。。[i+j]就是指数。。
for(i=0;i<=a+b*2;i++)
{
c1[i]=c2[i];//把c2的赋值给c1.。
c2[i]=0;
}
for(i=0;i<=a+b*2;i++)
for(j=0;j<=c*5;j+=5)//和上面类似。。
c2[i+j]+=c1[i];
for(i=0;i<=a+b*2+c*5;i++)
{
c1[i]=c2[i];
c2[i]=0;
}
for(i=0;i<=sum;i++)
{
if(c1[i]==0)
{
cout<<i<<endl;
break;
}
}
if(i==sum+1)
cout<<i<<endl;
}
return 0;
}
//接下来是把分开的和起来。。
/*
#include <stdio.h>
#include <iostream>
using namespace std;
int a[8001],b[8001];
int c[]={1,2,5};
int main()
{
int i,j,k,n[3],s;
while(scanf("%d%d%d",&n[0],&n[1],&n[2])!=EOF,n[0]+n[1]+n[2])
{
s=n[0]*1+n[1]*2+n[2]*5;
if(n[0]==0)
printf("1\n");
else
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
for(i=0;i<=n[0];i++)
a[i]=1;
for(i=1;i<3;i++)
{
for(j=0;j<=s;j++)
for(k=0;k*c[i]+j<=s&&k<=n[i];k++)//k*c[i]+j<=s总的金额不能超过最大。k<=n[i] K是使用相应面值的数量 因此不能超过给定的上限 就是程序对应输入值
b[k*c[i]+j]+=a[j];
for(j=0; j<=s; j++)
{
a[j]=b[j];
b[j]=0;
}
}
for(i=0; i<=s+1; i++)
if(a[i]==0)
{
printf("%d\n",i);
break;
}
}
}
return 0;
}*/
//方法2暴力法:
/*
#include <iostream>
#include <stdio.h>
using namespace std;
int main()
{
int a,b,c;
int used[10000];
while(scanf("%d%d%d",&a,&b,&c)!=EOF)
{
int ans=-1;
memset(used,false,sizeof(used));
if(a==0&&b==0&&c==0)break;
for(int i=0;i<=a;i++)
for(int j=0;j<=b;j++)
for(int k=0;k<=c;k++)
used[i*1+j*2+k*5]=true;
for(i=1;i<=a+b*2+c*5;i++)
if(used[i]==false)
break;
printf("%d\n",i);
}
return 0;
}*/