整数的划分(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)种。