题目大意:给出1、2、5分硬币数目,问不能构成的面值的最小值是多少。
生成函数:
(1+x+x^2+x^3……x^k1)*(1+x^2+x^4……x^2*k2)*(1+x^5+x^10……x^5*k3)
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int c[8005],c0[8005],v[4]={0,1,2,5},a[4]; void solve() { int i,j,k,t,m=0; for(i=1;i<=3;++i) m+=a[i]*v[i]; //最高次数 memset(c,0,sizeof(c)); memset(c0,0,sizeof(c0)); for(i=0;i<=a[1];++i) c0[i]=1; for(k=2;k<=3;++k) { for(i=0;i<=m;++i) for(j=0,t=0;t<=a[k];j+=v[k],++t) c[i+j]+=c0[i]; for(i=0;i<=m;++i) c0[i]=c[i],c[i]=0; } for(i=0;i<=m&&c0[i];++i); printf("%d\n",i); } int main() { while(~scanf("%d%d%d",&a[1],&a[2],&a[3])&&(a[1]+a[2]+a[3])>0) solve(); return 0; }
好吧,此题其实并不需要用“牛刀”的。
若面值为1的硬币数量为0,则面值1显然是无法构成的;
若有1,则从1到n1+2*n2的数肯定都能拼成。
考虑5的个数,若n1+2*n2>4,则n1+2*n2+5*n3面值以下均可得到,若n1+2*n2不能达到4,则结果即为n1+2*n2+1