题目
一个正整数n可以表示成若干个正整数之和,形如:n=n1+n2+…+nk,其中n1≥n2≥…≥nk,k≥1
。
我们将这样的一种表示称为正整数n的一种划分。
现在给定一个正整数n,请你求出n共有多少种不同的划分方法。
输入格式
共一行,包含一个整数n。
输出格式
共一行,包含一个整数,表示总划分数量。
由于答案可能很大,输出结果请对109+7
取模。
数据范围
1≤n≤1000
分析
这题可以用背包的思维来解决问题,我们可以f[i][j]表示为遍历到j时,总和为i的组合数量。这样状态转移方程就变成了:f[i][j]=sum(f[i-1][j]+f[i-2][j]……f[0][j]).其中f[0][0]=1;
这题就变成了完全背包问题,因为每一个数字都可以选任意次。
这样就可以和完全背包问题一起优化了
优化后的代码
#include <cstring>
#include <iostream>
using namespace std;
const int N=1005;
int f[N];
const int mod=1e9+7;
int main(){
int n;
cin >> n;
f[0]=1;
for(int i=1;i<=n;i++){//其中i表示遍历到第几个数
for(int j=i;j<=n;j++){//j表示总和
f[j]=(f[j]+f[j-i])%mod;//防止溢出,%mod
}
}
cout << f[n];
}