整数划分,将一个整数分解
//1.完全背包问题
// 状态表示 f[i][j]:从1到i挑选数字合成j,性质:数量
// 以选了多少个i来划分
// 状态计算:f[i][j]=f[i-1][j]+f[i-1][j-i]+...+f[i-s][j-s*i]
// f[i][j]=f[i-1][j]+f[i-1][j-i]+...+f[i-s][j-s*i]
// f[i][j-i]= +f[i-1][j-i]+...+f[i-s][j-s*i]
// 则有f[i][j]=f[i-1][j]+f[i][j-i];
// 即f[j]=f[j]+f[j-i](注:跟完全背包一样,体积从小到大循环)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010,mod=1e9+7;
int n;
int f[N];
int main()
{
cin>>n;
f[0]=1;//当一个数不选时,f[0]=1,其余都是0
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
f[j]=(f[j]+f[j-i])%mod;
cout<<f[n]<<endl;
return 0;
}
//2.拓展做法
// 状态表示f[i][j]:所有总和是i,且恰好表示成j个数的和的方案;属性:数量
// 依据j个数中最小值是否为1划分
// 状态计算:f[i][j]=f[i-1][j-1]+f[i-j][j](所有减去1,还是j个数)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010,mod=1e9+7;
int n;
int f[N][N];
int main()
{
cin>>n;
f[0][0]=1;//总和是i,表示为i个数的方案数是1;
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
f[i][j]=(f[i-1][j-1]+f[i-j][j]);
int res=0;
//总数求和
for(int i=1;i<=n;i++)res=(res+f[n][i])%mod;
cout<<res<<endl;
return 0;
}