HDU 2189 悼念512汶川大地震遇难同胞――来生一起走 --生成函数

这题跟上两题也差不多。

把150以内的素数找出来,把素数的值看做硬币的面值,每个硬币的个数即ceil(150/prime[i]),因为再多也没用,最多组成n=150就行了,所以又回到了找硬币问题。用生成函数解之。

代码:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;

#define N 207



int prime[N],flag[N],num[N];

int c[7002],tc[7002];

int ci;



void doit()

{

    int i,j,n;

    ci = 0;

    for(i=2;i<=150;i++)

        flag[i]=1;

    for(i=2;i<=150;i++)

    {

        if(flag[i])

           prime[ci++]=i;

        for(j=0;j<ci&&i*prime[j]<=150;j++)

        {

            flag[i*prime[j]]=0;

            if(i%prime[j]==0)

               break;

        }

    }

}



int main()

{

    doit();

    int i,j,k,t,n;

    int maxi = 0;

    for(i=0;i<ci;i++)

    {

        num[i] = 150/prime[i]+1;

        maxi += prime[i]*num[i];

    }

    scanf("%d",&t);

    while(t--)

    {

        scanf("%d",&n);

        for(i=0;i<=maxi;i++)

            c[i] = tc[i] = 0;

        for(i=0;i<=prime[0]*num[0];i+=prime[0])

            c[i] = 1;

        for(i=1;i<ci;i++)

        {

            for(j=0;j<=maxi;j++)

            {

                for(k=0;k+j<=maxi && k<=prime[i]*num[i];k+=prime[i])

                    tc[k+j] += c[j];

            }

            for(j=0;j<=maxi;j++)

            {

                c[j] = tc[j];

                tc[j] = 0;

            }

        }

        printf("%d\n",c[n]);

    }

    return 0;

}
View Code

 

你可能感兴趣的:(HDU)