动态规划之01背包
来源:互联网 发布:python sin函数 编辑:程序博客网 时间:2024/05/18 15:56
有n件物品,每种只有一个,第i种物品的体积是Vi, 重量为Wi,选择一些物品装到一个容量为C的背包中,使得背包体积在不超过C的前提下重量尽量大
这是最基础的动态规划的问题,这类问题最重要的就是要找到状态转移方程。这里我们可以引用“阶段”的概念,也就是我们的每一次决策都是放在前一次决策的基础上,比如决定第i个物品是否要放入背包,就要在前i次决策的基础上进行比较。
我们再来看一下这个背包的状态转移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);这时的i是对前i-1个物品做完决策以后的第I次决策,j是此时的背包的重量,dp[i][j]的最优解是(不放第i件物品与上一个状态中已用j质量的价值,放了第i件物品与上一个状态中放了后质量为[j-weight[i]]+第i件物品的价值)进行比较
#include<bits/stdc++.h>using namespace std;const int maxn=1005;int weight[maxn],value[maxn],dp[maxn][maxn];int main(){ int N,V; cin>>N>>V;//N是一共的物品数量,V是背包所能承受的最大质量 for(int i=1;i<=N;i++) cin>>weight[i];//每件物品的质量 for(int i=1;i<=N;i++) cin>>value[i];//每件物品的价值 //dp[i][j]表示将前i件物品处理完后,背包已经用了大小为j的质量,所对应的的最大价值 for(int i=1;i<=N;i++) {//将第i件物品放在前面(i-1)件物品的状态上 //j为已用体积!!!!! for(int j=0;j<=V;j++) {//j从第i件物品的质量开始,因为j为已用体积,也就是从已用体积为j的状态中挑出最优解 if(j<weight[i])dp[i][j]=(i==1?0:dp[i-1][j]); else dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]); } } cout<<dp[N][V]<<endl; return 0;}
这里还有一个更厉害的操作,在前面我们用的数组是二维的,也就是我们要对每一个阶段的大于Vi的所有状态进行更新,这样看来时间是不能更快了,但在空间上我们还可以更优化, 既然每一个东西只用一次,我们可不可以在输入的时候就对每个阶段进行决策?也就是把二维数组变成1维,而每次决策放在输入后,答案当然是可以的
#include<bits/stdc++.h>using namespace std;int main(){ int N,V; cin>>N>>V; vector<int>dp(10000,0); while(N--) { int weight, value; cin>>weight>>value; for(int j=V;j>=weight;j--) dp[j]=max(dp[j],dp[j-weight]+value); } cout<<dp[V]<<endl; return 0;}
这里我们为了保证每种物品只用了一次,我们的状态遍历必须从后往前,因为从前往后的话,我们的每次决策都会用到前面的数据,而我们前面的数据有可能是已经更新过的,所以我们必须从后往前更新
阅读全文
0 0
- 01背包之动态规划
- 动态规划之01背包
- 动态规划之背包01
- 动态规划之01背包
- 动态规划之01背包
- 动态规划之01背包
- 动态规划之01背包
- 动态规划之01背包
- 动态规划之01背包
- 动态规划之01背包
- 动态规划之01背包
- 动态规划之背包
- 动态规划之01背包,完全背包,多重背包
- 动态规划之01背包,完全背包,多重背包模板
- 动态规划之01背包问题
- 【初学动态规划】之01背包问题
- 动态规划之01背包问题
- 动态规划之01背包问题
- Prim算法
- n-gram python实现(基于sklearn)
- HDU 3065 病毒侵袭持续中(字典树)
- HDU
- php设计模式
- 动态规划之01背包
- 51nod 1237 杜教筛
- ZXing 二维码扫描
- iOS swift 面试题
- JAVA基础知识点
- JSTL 学习使用笔记
- mongodb释放内存
- 阿里云ECS之完整流程搭建:CentOS 7.3+Nginx 1.12.1+php 7.1 + MaraiaDB 5.5.52 + PhpMyAdmin 4.6.6
- Mac安装配置Tomcat