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