计蒜客模拟(三) 结果填空:数字拆分
问题分析
我们可以把这道题当作一道完全背包问题来求解,把每一个数字当作一个阶段,每个数字可以选择多次。
不知道完全背包问题的可以参考,这一篇。
我们设d[ i ][ i ]为数字i拆分方法数。
我们可以写出状态转移方程
\[d[i][j] = \sum\limits_{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; }