整数划分
/*****(一)将n划分成若干不同整数之和的划分数************
dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况
dp[0][0] = 1
dp[i][j] = dp[i-j][j-1] + dp[i][j-1];(j<=i)
= dp[i][i] (j >i)
=>ans = dp[n][n]
/*****(二)将n划分成若干正整数之和的划分数*************
dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况
与(一)区别,j可重复
dp[0][0] = 1
dp[i][j] = dp[i-j][j] + dp[i][j-1];(j<=i)
= dp[i][i] (j >i)
=>ans = dp[n][n]
/*****(三)将n划分成k个正整数之和的划分数*************
dp[i][j]表示将整数i划分成j个正整数的划分数,考虑j组数中含不含1
dp[0][0] = 1
dp[i][j] = dp[i-1][j-1] + dp[i-j][j];
如果不包含1,那么每组数至少为2,从每堆数中各拿出1还能够成j堆数dp[i-j][j]
=>ans = dp[n][k]
/*****(四)将n划分成最大数不超过k的划分数************
dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况
是(二)的特例
dp[0][0] = 1
dp[i][j] = dp[i-j][j] + dp[i][j-1];(j<=i)
= dp[i][i] (j >i)
=>ans = dp[n][k]
/*****(五)将n划分成若干个 奇正整数之和的划分数******
dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况
dp[0][0] = 1;
j是奇数,正常判断
dp[i][j] = dp[i-j][j] + dp[i][j-1];(j<=i)
= dp[i][i] (j >i)
j是偶数,dp[i][j] = dp[i][j-1]//往下递推
=>ans = dp[n][n]
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int maxn = 1e3 + 7; 5 6 int dp[maxn][maxn], n, k, ans[6]; 7 8 int main() { 9 #ifndef ONLINE_JUDGE 10 freopen("../in.txt", "r", stdin); 11 #endif // ONLINE_JUDGE 12 while (scanf("%d%d", &n, &k) == 2) { 13 //*****(一)将n划分成若干不同整数之和的划分数************ 14 memset(dp, 0, sizeof(dp)); 15 dp[0][0] = 1; 16 for (int i = 0; i <= n; ++i) { 17 for (int j = 1; j <= n; ++j) { 18 if (j <= i) dp[i][j] = dp[i - j][j - 1] + dp[i][j - 1]; 19 else dp[i][j] = dp[i][i]; 20 } 21 } 22 ans[1] = dp[n][n]; 23 //*****(二)将n划分成若干正整数之和的划分数************* 24 memset(dp, 0, sizeof(dp)); 25 dp[0][0] = 1; 26 for (int i = 0; i <= n; ++i) { 27 for (int j = 1; j <= n; ++j) { 28 if (j <= i) dp[i][j] = dp[i - j][j] + dp[i][j - 1]; 29 else dp[i][j] = dp[i][i]; 30 } 31 } 32 ans[2] = dp[n][n]; 33 ans[4] = dp[n][k]; 34 //*****(三)将n划分成k个正整数之和的划分数************* 35 memset(dp, 0, sizeof(dp)); 36 dp[0][0] = 1; 37 for (int i = 0; i <= n; ++i) { 38 for (int j = 1; j <= i; ++j) { 39 dp[i][j] = dp[i - 1][j - 1] + dp[i - j][j]; 40 } 41 } 42 ans[3] = dp[n][k]; 43 //*****(四)将n划分成最大数不超过k的划分数************ 44 //(四)是(二)的特殊情况 45 //*****(五)将n划分成若干个奇正整数之和的划分数****** 46 memset(dp, 0, sizeof(dp)); 47 dp[0][0] = 1; 48 for (int i = 0; i <= n; ++i) { 49 for (int j = 1; j <= n; ++j) { 50 if (j & 1) { 51 if (j <= i) dp[i][j] = dp[i - j][j] + dp[i][j - 1]; 52 else dp[i][j] = dp[i][i]; 53 } else dp[i][j] = dp[i][j - 1]; 54 } 55 } 56 ans[5] = dp[n][n]; 57 for (int i = 1; i <= 5; ++i) printf("case %d ans = %d\n", i, ans[i]); 58 } 59 return 0; 60 } 61 /* 62 /*****(一)将n划分成若干不同整数之和的划分数************ 63 dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况 64 dp[0][0] = 1 65 dp[i][j] = dp[i-j][j-1] + dp[i][j-1];(j<=i) 66 = dp[i][i] (j >i) 67 =>ans = dp[n][n] 68 69 /*****(二)将n划分成若干正整数之和的划分数************* 70 dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况 71 与(一)区别,j可重复 72 dp[0][0] = 1 73 dp[i][j] = dp[i-j][j] + dp[i][j-1];(j<=i) 74 = dp[i][i] (j >i) 75 =>ans = dp[n][n] 76 77 /*****(三)将n划分成k个正整数之和的划分数************* 78 dp[i][j]表示将整数i划分成j个正整数的划分数,考虑j组数中含不含1 79 dp[0][0] = 1 80 dp[i][j] = dp[i-1][j-1] + dp[i-j][j]; 81 如果不包含1,那么每组数至少为2,从每堆数中各拿出1还能够成j堆数dp[i-j][j] 82 =>ans = dp[n][k] 83 /*****(四)将n划分成最大数不超过k的划分数************ 84 dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况 85 是(二)的特例 86 dp[0][0] = 1 87 dp[i][j] = dp[i-j][j] + dp[i][j-1];(j<=i) 88 = dp[i][i] (j >i) 89 =>ans = dp[n][k] 90 /*****(五)将n划分成若干个 奇正整数之和的划分数****** 91 dp[i][j]表示将整数i划分成不超过j的划分数,分含不含j两种情况 92 dp[0][0] = 1; 93 j是奇数,正常判断 94 dp[i][j] = dp[i-j][j] + dp[i][j-1];(j<=i) 95 = dp[i][i] (j >i) 96 j是偶数,dp[i][j] = dp[i][j-1]//往下递推 97 =>ans = dp[n][n] 98 */