2 条题解
-
1
#include<bits/stdc++.h> using namespace std; #define ll long long const int mod = 1e9 + 7; int n; int main() { cin >> n; //因为严格递增,所以每个数只能选择一次,那就是从小于等于n的数中选择若干数 //每个数只能选择一次,最终凑成n的形式,问方案数,因为每个数只能选择一次那就可以用01背包,得到状态数组 vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0)); //dp[i][j]:从前i个数中选取若干数凑成j的总方案数 dp[0][0] = 1; //初始化,用于后续递推,且凑成0也为一种方案 for (int i = 1; i <= n; i++) {//枚举前i个数 for (int j = 0; j <= n; j++) {//枚举凑成的结果j //不选择i: dp[i][j] = dp[i - 1][j]; //选择i if(j>=i)dp[i][j] = (dp[i][j] + dp[i - 1][j - i]) % mod; } } cout << dp[n][n]; return 0; } -
1
递归方程为:dp[n][m]= dp[n][m-1]+ dp[n-m][m-1]
dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。 同样划分情况分为两种情况: a.划分中每个数都小于m,相当于每个数不大于 m-1,划分数为 dp[n][m-1]. b.划分中有一个数为 m.在n中减去m,剩下相当对n-m进行划分,并且每一个数不大于m-1,故划分数为 dp[n-m][m-1] c++代码如下:
#include<bits/stdc++.h> using namespace std; const int N=1e3+10,M=1e9+7; int f[N][N]; int main(){ int n,ans=0;cin>>n; f[1][1]=1; for(int i=2;i<=n;i++){ for(int j=2;j<=i;j++){ f[i][j]=(f[i-1][j-1]+f[i-j][j-1])%M; } } for(int i=1;i<=n;i++){ ans=(ans+f[n][i])%M; } cout<<ans; }
- 1
信息
- ID
- 47
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 3
- 标签
- 递交数
- 207
- 已通过
- 71
- 上传者