HDU 1398-Square Coins (雌函数)

HDU 1398-Square Coins (母函数)

题目链接】click here~~

题目大意】题意:硬币面值为平方数,面值分别为1,4,9,16......289 (=17^2),让你求对于面值n,你用以上面值的硬币有多少种拼法。

【解题思路】:母函数,设
1个1元的钞票可以用函数1+x表示,
1个4元的钞票可以用函数1+x^4表示,
1个9元的钞票可以用函数1+x^9表示,
1个16元的钞票可以用函数1+x^16表示,

几种钱币的组合的情况,可以用以上几个函数的乘积表示:
(1+x)(1+x^4)(1+x^9)(1+x^16)

=(1+x^4+x+x^5)(1+x^16+x^9+x^25)

=1+x^16+x^9+x^25+x^4+x^20+x^13+x^29+x+x^17+x^10+x^26+x^5+x^21+x^14+x^30         

从上面的函数知道:可拼出从1元到10元,系数便是方案数。
例如右端有x^5 项,即称出5元的方案有1:5=4+1;同样,10=1+9;14=1+9+4。
故称出6克的方案有1,称出14克的方案有1?

反过来就是:

求组成n的可拼组合总数
(1+x^1+x^2+x^3+....+x^n)*(1+x^4+x^8+x^16+....+x^n)*(1+x^9+x^18+x^27+....+x^n)......(1+x^m+x^2m+x^3m+....+x^n)

代码:

/*
 在i遍历表达式时,把i<=nNum改成了i*i<=nNum,其次在k遍历指数时把k+=i变成了k+=i*i;
*/
#include <bits/stdc++.h>
using namespace std;
int C1[305],C2[305];
int main()
{
    int n,m,t;
    while(cin>>t&&t)
    {
        for(int i=0; i<=t; ++i){
            C1[i]=1;
            C2[i]=0;
        }
        for(int i=2; i*i<=t; ++i){
            for(int j=0; j<=t; ++j){
                for(int k=0; k+j<=t; k+=i*i)
                C2[k+j]+=C1[j];
            }
          memcpy(C1,C2,sizeof(C2));
          memset(C2,0,sizeof(C2));
        }
        printf("%d\n",C1[t]);
    }
    return 0;
}