HDU 1085 Holding Bin-Laden Captive --生成函数第一题

生成函数题。

题意:有币值1,2,5的硬币若干,问你最小的不能组成的币值为多少。

解法:写出生成函数:

然后求每项的系数即可。

因为三种硬币最多1000枚,1*1000+2*1000+5*1000=8000,那么多项式乘积的最高次数为8000
用c保存累计相乘各项的系数,tc保存c和当前项相乘的系数

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define N 8007

int c[N],tc[N];

int main()
{
    int num[3],cnt[3] = {1,2,5};
    int i,j,k;
    while(scanf("%d%d%d",&num[0],&num[1],&num[2])!=EOF)
    {
        if(num[0] == 0 && num[1] == 0 && num[2] == 0)
            break;
        int maxi = num[0] + 2*num[1] + 5*num[2];

        for(i=0;i<8001;i++)
            c[i] = 0,tc[i] = 0;

        for(i=0;i<=cnt[0]*num[0];i+=cnt[0])  //第一个多项式的系数
            c[i] = 1;

        for(i=1;i<3;i++)  //第几个多项式
        {
            for(j=0;j<=maxi;j++)  //累计的x^j的系数
            {
                for(k=0;k+j<=maxi && k<=cnt[i]*num[i];k+=cnt[i])  //当前x^k的系数
                    tc[k+j] += c[j];
            }
            for(j=0;j<=maxi;j++)  //将结果保存到累计结果数组c中,重置tc
            {
                c[j] = tc[j];
                tc[j] = 0;
            }
        }
        for(i=0;i<=maxi;i++)
            if(c[i] == 0)
                break;
        cout<<i<<endl;
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/whatbeg/p/3728545.html