算法基础之整数划分
2023-12-28 02:34:59
整数划分
- 核心思想: 计数类dp
背包做法
-
f[i][j] 表示 取 1 – i 的物品 总容量为j的选法数量
-
f[i][j] = f[i-1][j] + f[i-1][j-v[i]] +f[i-1][j-2v[i]] +f[i-1][j-3v[i]] +……+f[i-1][j-kv[i]]
-
f[i][j-v[i]] = f[i-1][j-v[i]] +f[i-1][j-2v[i]] +f[i-1][j-3v[i]] +……+f[i-1][j-kv[i]]
-
f[i][j] = f[i-1][j] + f[i][j-v[i]]; (本题中 v[i] = i)
-
#include<iostream> #include<cstring> #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种 for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) //f[i][j - i] = f[i][j - i] + f[i][j - 2] + ... + f[i][j - k] //f[j-i] f[j] = (f[j] + f[j - i]) % mod; cout<<f[n]; }
-
-
dp做法
-
f[i][j] 表示总和为i 总共j个数的方案数量
-
将f[i][j] 分为 最小值是1的方案 和 最小值大于1的方案 两部分 (不重不漏)
- 最小值是1: 在集合中–1 –> f[i-1][j-1] 总和为i-1 个数为j-1
- 最小值大于1 : 将集合总每个数-1 –> f[i-j][j] 总和为i-j 个数为j
-
则f[i][j] = f[i-1][j-1] + f[i-j][j]
-
结果 : res = f[n][1] + f[n][2] +f[n][3] + … + f[n][n] (1个数的方案+2个数的方案+ … +n个数的方案)
-
#include<iostream> #include<cstring> #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; for(int i=1;i<=n;i++) { for(int j=1;j<=i;j++) //总和为i 个数最多为i { 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; cout<<res; }
-
-
文章来源:https://blog.csdn.net/Pisasama/article/details/135256980
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!