背包问题(dp初步)
来源:互联网 发布:青岛知豆在哪租的 编辑:程序博客网 时间:2024/05/21 11:03
问题一:0-1背包问题
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
如下表,利用动态规划思想从左到右,从上到下生成所有状态:
代码实现:
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;const int N=5;//物品数目const int V=10;//背包容量int main(){ int weight[10]={-1,2,2,6,5,4}; int value[10]={-1,6,3,5,4,6}; int f[10][15]={0}; for(int i=1;i<=N;i++) { for(int j=0;j<=V;j++) { if(weight[i]<=j) f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]]+value[i]); else f[i][j]=f[i-1][j]; } } cout<<f[N][V]<<endl; return 0;}
进一步思考,代码可以优化如下:
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;const int N=5;//物品数目const int V=10;//背包容量int main(){ int weight[10]={-1,2,2,6,5,4}; int value[10]={-1,6,3,5,4,6}; int f[15]={0}; for(int i=1;i<=N;i++) { for(int j=V;j>=0;j--) { if(weight[i]<=j) f[j]=max(f[j],f[j-weight[i]]+value[i]); } } cout<<f[V]<<endl; return 0;}
问题二:完全背包问题
完全背包问题:一个背包总容量为V,现在有N个物品,第i个 物品体积为weight[i],价值为value[i],每个物品都有无限多件,现在往背包里面装东西,怎么装能使背包的内物品价值最大?
状态转移方程为:
f[i+1][j]=max(f[i][j-k*weight[i+1]]+k*value[i+1]),其中0<=k<=V/weight[i+1]
代码实现:
#include<cstdio>#include<iostream>#include<algorithm>using namespace std;const int N=5;//物品数目const int V=10;//背包容量int main(){ int weight[10]={-1,2,2,6,5,4}; int value[10]={-1,6,3,5,4,6}; int f[15]={0}; for(int i=1;i<=N;i++) { for(int j=1;j<=V;j++) { if(weight[i]<=j) f[j]=max(f[j],f[j-weight[i]]+value[i]); } } cout<<f[V]<<endl; return 0;}
问题三:多重背包问题
有一个容量为V的背包和N件物品,第i件物品最多有Num[i]件,每件物品的重量是weight[i],收益是value[i]。在不超过背包容量的情况下,最多能获得多少价值或收益
多重背包二进制拆分实现:
跟完全背包一样的道理,利用二进制的思想将n[i]件物品i拆分成若干件物品,目的是在0-n[i]中的任何数字都能用这若干件物品代换,另外,超过n[i]件的策略是不允许的。方法是将物品i分成若干件,其中每一件物品都有一个系数,这件物品的费用和价值都是原来的费用和价值乘以这个系数,使得这些系数分别为1,2,4,…,2^(k-1),n[i]-2^k+1,且k满足n[i]-2^k+1>0的最大整数。例如,n[i]=13,就将该物品拆成系数为1、2、4、6的四件物品。分成的这几件物品的系数和为n[i],表明不可能取多于n[i]件的第i种物品。另外这种方法也能保证对于0..n[i]间的每一个整数,均可以用若干个系数的和表示。
状态转移方程:
dp[i][v]=max{ dp[i-1][v-k*c[i]]+k*w[i] }, 0<=k<=num[i]
代码实现:
#include<iostream>using namespace std;const int N=3;const int V=8;int weight[N+1]={-1,1,2,2};int value[N+1]={-1,6,10,20};int num[N+1]={-1,10,5,2};int f[V+1]={0};void _01pack(int _weight,int _value){ for(int v=V;v>=_weight;v--) f[v]=max(f[v],f[v-_weight]+_value);}void completepack(int _weight,int _value){ for(int v=_weight;v<=V;v++) f[v]=max(f[v],f[v-_weight]+_value);}int multipack(){ int k=1; int coun=0; for(int i=1;i<=N;i++) { if(weight[i]*num[i]>=V) completepack(weight[i],value[i]); else { k=1; coun=num[i]; while(k<=coun) { _01pack(k*weight[i],k*value[i]); coun-=k; k*=2; } _01pack(coun*weight[i],coun*value[i]); } } return f[V];}int main(){ cout<<multipack()<<endl; return 0;}
阅读全文
0 0
- 背包问题(dp初步)
- 背包问题初步
- 背包问题(DP、回溯)
- 饭卡(背包问题)DP
- DP 背包问题 01背包
- DP问题初步(杭电1003)
- 背包问题初步入门--背包1
- 背包问题初步入门--背包2 poj1276
- 01背包问题(动态规划DP)
- 0—1背包问题(dp)
- Piggy-Bank(dp完全背包问题)
- 背包问题(一维dp)
- 01背包问题(DP解决)
- DP算法----背包问题(上)
- 01背包问题讲解(dp)
- 完全背包问题讲解(dp)
- 完全背包问题讲解(dp)
- 01背包问题(动态规划DP)
- centos6.5 安装git
- 安卓app启动时间
- 【多校训练】hdu 6077 Time To Get Up
- android 6.0 logcat机制(一)java层写log,logd接受log
- 【Unity3D】关于发布WebGL的一些问题记要
- 背包问题(dp初步)
- C#异常处理
- ZOJ 3452 Doraemon's Stone Game
- MySQL演进图
- 【Ex.】三子棋的实现
- lvs群集DR模式搭建
- 在 android 4.4 下预置app
- 数据库ACID特性
- eclipse配置pydev