整数划分问题
整数的划分(Partition of an Integer)详解
1. 什么是整数划分
整数划分是指将一个正整数表示为一系列正整数之和的方式。顺序不同但数字相同的划分视为同一种划分。例如:
- 4的划分有:
- 4
- 3 + 1
- 2 + 2
- 2 + 1 + 1
- 1 + 1 + 1 + 1
2. 递归方法实现
方法一:不考虑顺序的划分
#include <iostream>
using namespace std;
// 计算整数n的划分数,最大加数不超过m
int partition(int n, int m) {
if (n == 0) return 1; // 基本情况:0只有一种划分方式
if (m == 0) return 0; // 没有可用的加数
if (n < m) return partition(n, n); // 最大加数不能超过n本身
// 划分中包含m的情况 + 不包含m的情况
return partition(n - m, m) + partition(n, m - 1);
}
int main() {
int n = 4;
cout << "整数 " << n << " 的划分数为: " << partition(n, n) << endl;
return 0;
}
方法二:输出所有划分方式
#include <iostream>
#include <vector>
using namespace std;
void printPartitions(int n, int max, vector<int>& current) {
if (n == 0) {
// 找到一个划分,输出它
for (int i = 0; i < current.size(); i++) {
if (i != 0) cout << "+";
cout << current[i];
}
cout << endl;
return;
}
for (int i = min(max, n); i >= 1; i--) {
current.push_back(i);
printPartitions(n - i, i, current);
current.pop_back();
}
}
int main() {
int n = 4;
vector<int> current;
cout << "整数 " << n << " 的所有划分方式:" << endl;
printPartitions(n, n, current);
return 0;
}
3. 动态规划方法实现
递归方法效率较低,可以使用动态规划来优化:
#include <iostream>
#include <vector>
using namespace std;
int countPartitionsDP(int n) {
vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
// 基本情况
for (int i = 0; i <= n; i++) {
dp[0][i] = 1; // 0只有一种划分方式
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (j > i) {
dp[i][j] = dp[i][i];
} else {
dp[i][j] = dp[i - j][j] + dp[i][j - 1];
}
}
}
return dp[n][n];
}
int main() {
int n = 4;
cout << "整数 " << n << " 的划分数为: " << countPartitionsDP(n) << endl;
return 0;
}
4. 算法分析
-
时间复杂度:
- 递归方法:O(2^n)(指数级)
- 动态规划:O(n^2)(多项式级)
-
空间复杂度:
- 递归方法:O(n)(调用栈深度)
- 动态规划:O(n^2)(二维数组)
5. 应用场景
整数划分问题在以下领域有应用:
- 组合数学
- 统计学中的分组问题
- 计算机科学中的资源分配问题
- 数论研究
6. 扩展
如果需要考虑划分顺序(即1+2+1和1+1+2视为不同划分),则问题变为"组合"问题,解决方案会更简单,总数为2^(n-1)种。

浙公网安备 33010602011771号