有1,4,9,16....17 * 17的硬币无数个,问能凑成n的方法有几种
母函数G( x ) = ( 1 + x + x ^ 2 + x ^ 3 + ...) * (1 + x ^ 4 + x ^ 8 + x ^ 16 + ...) * (1 + x ^ 9 + x ^ 18 + x ^ 27 + ..) * ...
x的指数表示能凑成的面值,x的系数表示方法数。
#include
#include
using namespace std;
const int maxn =300 +5;
int a[maxn],b[maxn],c[maxn];
void f(int n)
{
for (int i =0; i <= n; i ++) {
a[i] = 1;b[i] =1;c[i] =0;
}
for (int k =2; k <=17; k ++) {
for (int i =0; i <= n; i ++) {
for (int j =0; i + j <= n; j += k * k) {
c[i + j] += a[i] * b[j];
}
}
for (int i =0; i <= n; i ++) {
a[i] = c[i] ;
c[i] = 0;
}
}
//ans = a
}
int main()
{
int n;
f(maxn -1);
while (scanf("%d",&n) !=EOF && n) {
printf("%d\n",a[n]);
}
return 0;
}
//hdu1085
给定面值为1,2,5的硬币个数
void f(int c1,int c2,int c3)
{
int n = c1 + 2 * c2 + 5 * c3;
memset(a, 0, sizeof(a));
for(int i = 0;i <= c1;i ++) a[i] = 1ll;
memset(c, 0, sizeof(c));
for (int i = 0; i <= n; i ++) {
for (int j = 0;j <= c2; j ++) {//个数
c[i + j * 2] += a[i] ;//因为新乘的式子系数总为1,所以直接加就好
}
}
for (int i = 0; i <= n; i ++) {
a[i] = c[i];c[i] = 0;
}
for (int i = 0; i <= n; i ++) {
for (int j = 0; j <= c3; j ++) {
c[i + j * 5] += a[i];
}
}
}