方法1:完全背包法
1.状态定义:
f[i][j]
: 表示只从1 ~ i中选,且总体积恰好为j的方案数
#include <bits/stdc++.h>
using namespace std;
const int N = 1010, MOD = 1e9 + 7;
int n;
int f[N];
//状态定义: f[i][j] : 只从 1 ~ i 中选,且总体积恰好j的集合的数量
int main()
{
scanf("%d",&n);
f[0] = 1; //一个数都没有选也是一种方案
//完全背包
for(int i = 1; i <= n; i++){
for(int j = i ; j <= n; j++){
f[j] = (f[j] + f[j - i]) % MOD;
}
}
printf("%d",f[n]);
return 0;
}
第二种方法
1.状态定义:
f[i][j]
: 总和为 i, 分成 j 个数的方案
2.状态计算:最小值为1的情况和,最小值大于1的情况
最小值为1的情况 :
说明每个方案都存在1,先去掉1,合为 i - 1,分成 j - 1个数的和的方案
最小值大于1的情况:
所有总和为 i,表示的时j个数的和,并且每一个数都严格大于1,因此对每一个数都先减去 1
j个数每一个书都减去1,总和为i - j的就 j个数的和
最后需要每个数的方案数累加
#include <bits/stdc++.h>
using namespace std;
const int N = 1010, MOD = 1e9 + 7;
int n;
int f[N][N];
int main(){
scanf("%d",&n);
f[0][0] = 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]) % MOD;
}
}
int res = 0;
for(int i = 1; i <= n; i++){
res = (res + f[n][i]) % MOD;
}
printf("%d",res);
return 0;
}
标签:方案,int,个数,最小值,整数,数都,划分,1e9
From: https://www.cnblogs.com/ltphy-/p/18405390