【题目链接】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; }
时间: 2024-10-22 12:43:42