思路:递推or dp
f[i][j]表示要分解i且最小数字为j的情况
f[i][j] += f [ i-2 * j ][ j ] ( i-2*j >= j ),
f[i][j] += 1 ( i == 2 * j )
初始 f[i][i]=1
1 /* 2 State:Accepted 3 Time:2013.3.2 4 */ 5 #include <iostream> 6 #include <cstring> 7 #include <string> 8 #include <cstdlib> 9 #include <fstream> 10 #include <cmath> 11 #include <algorithm> 12 using namespace std; 13 const int maxn = 250; 14 long long f[maxn][maxn]; 15 int n; 16 17 void work(){ 18 for (int i = 0; i <= maxn; ++i) f[i][i] = f[i][0] = 1; 19 f[1][1] = f[2][1] = f[2][2] = 1; 20 for (int i = 3; i <= maxn ; ++i) 21 for (int j = 1; j <= i/2 ; ++j){ 22 if (j * 2 == i) ++f[i][j]; 23 else 24 for (int k = j; k <= i - 2 * j ; ++k) 25 f[i][j] += f[i - 2*j][k]; 26 } 27 28 } 29 30 void solve(){ 31 long long ans = 0; 32 for (int i = 0; i <= n/2 ; ++i) 33 ans += f[n][i]; 34 printf("%d %lld\n", n, ans); 35 } 36 int main(){ 37 freopen("poj1221.in","r",stdin); 38 freopen("poj1221.out","w",stdout); 39 work(); 40 scanf("%d",&n); 41 while ( n ){ 42 solve(); 43 scanf("%d",&n); 44 } 45 fclose(stdin); 46 fclose(stdout); 47 }