![](https://img-blog.csdnimg.cn/20190304203552269.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxOTk4OTM4,size_16,color_FFFFFF,t_70)
问题分析
我们可以把这道题当作一道完全背包问题来求解,把每一个数字当作一个阶段,每个数字可以选择多次。
不知道完全背包问题的可以参考,这一篇。
我们设d[ i ][ i ]为数字i拆分方法数。
我们可以写出状态转移方程
[d[i][j] = sumlimits_{j - k*i > = 0} {d[i - 1][j - k*i]} ]
d[0][0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= n; j++) {
for (int k = 0; k*i <= j; k++) {
d[i][j] += d[i - 1][j - k * i];
}
}
}
cout << d[n][n];
背包问题,可以优化空间复杂度,最终代码如下:
#include <cstdio>
#include <iostream>
using namespace std;
int d[10000];
int main() {
int n;
cin >> n;
d[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
d[j] += d[j - i];
}
}
cout << d[n];
return 0;
}