整数划分

Posted qldabiaoge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整数划分相关的知识,希望对你有一定的参考价值。



/*****(一)将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
", 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 */
View Code

 

以上是关于整数划分的主要内容,如果未能解决你的问题,请参考以下文章

动态规划整数划分及其变种

Java 求解划分字母区间

763. 划分字母区间

Leetcode 763 划分字母区间

贪心算法:划分字母区间

763.划分字母区间