【题目链接】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;
}
原文:http://blog.csdn.net/u013050857/article/details/45126957