终于搞定这道dp。。休息下。。
/*
zoj_1666 dp
看来我的dp还是烂成渣。。。想了N久还参考了别人的代码才搞懂。。
方法:f[i][j]表示用前i个钱币表示总钱数j的方法数。
可以得到递推式f[i][j]=f[i-1][j-k*i*i] ( k>=0 && k*i*i<=j )
稍微注意的是f[i][0]必须初始化为1。因为f[i][0]代表的是用第i+1个钱币表示总钱数,有一种方法。
*/
#include <iostream>
#include <cstdio>
#include <string.h>
#include <math.h>
using namespace std;
int f[18][301];
int main()
{
int i,j,k,n;
memset( f,0,sizeof(0) );
for( i=0;i<18;i++ )
f[i][0]=1;
for( i=1;i<301;i++ )
f[1][i]=1;
for( i=2;i<18;i++ )
{
for( j=1;j<301;j++ )
{
for( k=0;k*i*i<=j;k++ )
f[i][j]+=f[i-1][j-k*i*i];
}
}
while( cin>>n && n )
cout<<f[17][n]<<endl;
return 0;
}