2 10 30 0
1 4 27
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
ll dp[330];
/****************/
/*
* 简单dp问题
* dp[i]表示可以组成钱数i的方法种数;
* 状态方程 dp[i] += dp[i - j * j];
* 表示钱数为i的方法数等于它的所有子区间的方法数的累加;
*/
void unit()
{
dp[0] = 1; //钱数为0的方法数为1;
for(int i = 1; i <= 17; i++)
{
for(int j = 1; j <= 300; j++)
{
if(j - i * i < 0) continue;
dp[j] += dp[j - i * i];
}
}
}
int main()
{
int n;
unit();
while(true)
{
scanf("%d",&n);
if(!n) break;
printf("%I64d\n",dp[n]);
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int M = 1000;
ll a[M],b[M];
int main()
{
int n;
while(true)
{
scanf("%d",&n);
if(n == 0) break;
for(int i = 0; i <= n; i++)
{
a[i] = 1;
b[i] = 0;
}
for(int i = 2; i * i <= n; i++)
{
int t = i * i;
for(int j = 0; j <= n; j++)
{
for(int k = 0; k + j <= n; k += t)
{
b[k + j] += a[j];
}
}
for(int j = 0; j <= n; j++)
{
a[j] = b[j];
b[j] = 0;
}
}
printf("%I64d\n",a[n]);
}
return 0;
}
原文地址:http://blog.csdn.net/zsgg_acm/article/details/38961035