动态规划专题一:线性dp
2024-08-27 20:55:28
第一篇博客随笔,被迫写的bushi
上课讲的动态规划入门,还是得总结一下吧
背包
01背包
背包有容量限制,每一件物品只能够取一件(这就是为什么j从V至v[i]循环的原因)
思路:f数组表示当前状态的最佳情况,每一种物品就对应两种状态 1.选 2.不选,这样状态转移方程就出来了
1 #include<bits/stdc++.h>
2 using namespace std;
3 int N,V;
4 int v[10009],w[10009],f[50009];//v是物品的体积,w是物体的价值
5 int main(){
6 cin>>V>>N;
7 for(int i=1;i<=N;i++){
8 cin>>v[i]>>w[i];
9 w[i]*=v[i];
10 }
11 for(int i=1;i<=N;i++)
12 for(int j=V;j>=v[i];j--)
13 f[j]=max(f[j],f[j-v[i]]+w[i]);
14 cout<<f[V];
15 return 0;
16 }
完全背包
背包有容量限制,每一件物品能够取无数件(这就是为什么j从v[i]至V循环的原因)注意与01背包进行区分
思路:f数组表示当前状态的最佳情况(一样的),每一种物品就不止对应两种状态了,这就是与01背包的本质区别。所以状态转移方程不变,就只需要改变循环遍历的顺序啦
1 #include<bits/stdc++.h>
2 using namespace std;
3 int N,V;
4 int v[1005],w[1005],f[1005];//v是物品的体积,w是物品的价值
5 int main(){
6 cin>>N>>V;
7 for(int i=1;i<=N;i++) cin>>v[i]>>w[i];
8 for(int i=1;i<=N;i++)
9 for(int j=v[i];j<=V;j++)
10 f[j]=max(f[j],f[j-v[i]]+w[i]);
11 cout<<f[V];
12 return 0;
13 }
多重背包
背包有容量限制,每一件物品能够取规定数件(所以要拆分成01背包 啊这就是思路)三种做法:1直接拆分2二进制拆分3单调队列(因为太菜,单调队列代码以后贴)a bushi
1直接拆分
1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,m;
4 int f[10000002],v[1000005],w[1000005],c[1000005];
5 int main(){
6 cin>>n>>m;
7 for(int i=1;i<=n;i++)
8 cin>>v[i]>>w[i]>>c[i];
9 f[0]=0;//v是价值,w是体积
10 for(int i=1;i<=n;i++){
11 for(int j=1;j<=c[i];j++){
12 for(int k=m;k>=w[i];k--)
13 f[k]=max(f[k],f[k-w[i]]+v[i]);
14 }
15 }
16 cout<<f[m];
17 return 0;
18 }
2二进制拆分(注意输入时的预处理拆分)
1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,m,fl=1;
4 int f[10000002],v[1000005],w[1000005],c[1000005];
5 int main(){
6 cin>>n>>m;
7 for(int i=1;i<=n;i++){
8 int x,y,z;
9 cin>>x>>y>>z;
10 for(int j=1;j<=z;j=j<<1){
11 v[++fl]=j*x;w[fl]=j*y;
12 z-=j;
13 }
14 if(z>0) v[++fl]=x*z,w[fl]=y*z;
15 }
16 for(int i=1;i<=fl;i++){
17 for(int j=m;j>=w[i];j--){
18 f[j]=max(f[j],f[j-w[i]]+v[i]);
19 }
20 }
21 cout<<f[m];
22 return 0;
23 }
3单调队列(坑待填)
分组背包
背包有容量限制,每一组最多取一件物品
1 #include<bits/stdc++.h>
2 using namespace std;
3 int w[50],c[50],v,n,t,a[11][31],f[220];
4 int main(){
5 cin>>v>>n>>t;
6 for(int i=1;i<=n;i++){
7 int x;
8 cin>>w[i]>>c[i]>>x;
9 a[x][0]++;
10 a[x][a[x][0]]=i;
11 }
12 for(int k=1;k<=t;k++){
13 for(int j=v;j>=0;j--){
14 for(int p=1;p<=a[k][0];p++){
15 if(j>=w[a[k][p]]) f[j]=max(f[j-w[a[k][p]]]+c[a[k][p]],f[j]);
16 }
17 }
18 }
19 cout<<f[v];
20 return 0;
21 }
混合背包
就是把以上四种背包问题揉成了一道题,就分类讨论啊
就不贴代码了,贴一道题吧
基本上就这些了吧,遇到问题再更新吧
最新文章
- 学习WebSocket(二):使用Spring WebSocket做一个简单聊天室
- BZOJ4068 : [Ctsc2015]app
- JS中把字符串转成JSON对象的方法
- sql遍历树
- Java-使用js进行编码,后台解码。
- sonne_game网站开发03 spring-mvc+freemarker整合
- data pump(数据泵)
- LCS 小结
- [刷题]算法竞赛入门经典(第2版) 4-9/UVa1591 - Data Mining
- IP报文分片
- June 9. 2018, Week 23rd, Saturday
- 黑盒测试实践——day01
- Lua class
- 第二节:创建模型,使用Code First,配置映射关系
- Unity Profiler GPU Usage(GPU使用情况)
- web实现QQ头像上传截取功能
- nginx File not found 错误
- 翻译记忆软件-塔多思TRADOS经典教程_1
- python之threading.local
- OpenCV_火焰检测——完整代码