动态规划(递推)
用动态规划方法解决整数划分问题,既可以用自底向上的递推方法,也可以用自顶向下的递归方法。本帖先介绍递推方法,此方法类似于背包问题。某一种划分中的每一个数都可以视作背包问题中v=w的物品,在背包问题中dp(i,j)表示的状态为在前i个物品中选,总体积不超过j。此问题中仍然可以使用dp(i,j),表示的状态是从1∼i中选数,其总和等于j。由于并未限制这些数的选取次数,因此可以用完全背包问题的类似方法解决,先给出原始的dp图表:
选i的情况也可以类似的用dp(i,j−i)代替,原因如下:
同样,dp(i,x)只能从dp(i−1,x)得出,因此可以用一维dp表来记录。枚举顺序和完全背包问题一致
C++ 代码
#include <iostream>
using namespace std;
const int MOD = 1e9 + 7;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
int* dp = new int[n + 1]();
dp[0] = 1; //什么都不选视作1种方案
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
if (j >= i) {
dp[j] = (dp[j] + dp[j - i]) % MOD;
}
}
}
cout << dp[n] << endl;
delete[] dp;
return 0;
}