將正整數 n 表示為一系列遞減正整數之和:n = n₁ + n₂ + ... + nₖ,其中 n₁ ≥ n₂ ≥ ... ≥ nₖ ≥ 1, k ≥ 1。不同劃分個數記為 p(n)。例:p(6) = 11。
定義 q(n, m) 為:正整數 n 的所有劃分中,最大加數不超過 m 的劃分個數。目標 p(n) = q(n, n)。
#include <iostream>
#include <vector>
using namespace std;
// 遞歸 + 備忘錄 (動態規劃優化)
vector<vector<long long>> memo;
long long q(int n, int m) {
if (n < 1 || m < 1) return 0;
if (m == 1) return 1; // 邊界 1
if (m >= n) return q(n, n); // 邊界 2
if (memo[n][m] != -1) return memo[n][m];
if (m == n) {
memo[n][m] = q(n, n-1) + 1; // 遞歸 1
} else { // n > m > 1
memo[n][m] = q(n, m-1) + q(n-m, m); // 遞歸 2
}
return memo[n][m];
}
long long partition(int n) {
memo.assign(n+1, vector<long long>(n+1, -1));
return q(n, n);
}
int main() {
for (int i = 1; i <= 20; ++i) {
cout << "p(" << i << ") = " << partition(i) << endl;
}
// p(6) = 11 驗證
return 0;
}
若需輸出所有具體劃分方案,可在遞歸中維護路徑向量;若需生成第 k 個劃分(字典序),可利用 q(n, m) 的計數特性進行「跳躍式」構造,避免全量枚舉。