【01背包专题】--入门思考
来源:互联网 发布:国家统计局工业数据库 编辑:程序博客网 时间:2024/05/17 01:11
【问题】:
给出n个物品的大小,问容量为V的背包,最多能装入多大的物品?
【思路】
可以想到一种最最暴力的方法,每个物品可以选择放入背包或者不放入,那么n个物品就有2^n种放入背包的情况。
这种方法效率太低,不过可以从中得到点感悟。
1.对结果进行设计:定义输出用dp[V]表示,意思是对n个物品进行选择后,容量为V的背包最多能容纳dp[V]值大小的物品。
2.对过程进行分析:每个物品可以选择放入背包或者不放入,那么选择到第n个时:
a.第n个如果不放入背包,也就是说第n个物品不会占用到背包的容量,那么取到第n个时的dp[V]与取到第n-1个时的dp[V]是一样的;
b.第n个如果放入背包,占用了一部份背包容量,能提供给装前n-1个物品的背包容量只有V-a[n],那么取到第n个时的dp[V]就等于取到第n-1个时的dp[V-a[n]]加上当前选择放入的物品大小a[n]。
【如何实现】
过程分析中的前提是,当选择进行到第n个时,前n-1个物品的dp[0...V]都已经算出,选择进行到第1个物品时,dp[0...V]都为0,当然了,因为之前没物品。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-size:18px;">memset(dp,0,sizeof(dp));for(i=0;i<N;i++){ for(j=V;j-a[i]>=0;j--)//必须V到0遍历,否则同一个物品的选择会重复算造成错误。 {dp[j]=max(dp[j],dp[j-a[i]]+a[i]); }}</span></span>
【经典例题】
HDU 2546
思路:
还有5块的时候,可以任意买,当然是用来买最贵的了。所以先把剩余的钱拿出5块留到最后买最贵的,问题就转化成了如何花掉更多的剩余的钱。与上述如何使一个固定大小的背包装最大的物品本质相同。
代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-size:18px;">#include<stdio.h>#include<stdlib.h>#include<string>int n;int value[1001];int v;int dp[1001];//输出为v-dp[v]+5-value[n-1]int cmp(const void*a,const void*b){return *(int *)a-*(int *)b;}int max(int a,int b){return a>b?a:b;}int main(){while(~scanf("%d",&n)&&n){int i,j;for(i=0;i<n;i++){scanf("%d",&value[i]);}scanf("%d",&v);qsort(value,n,sizeof(value[0]),cmp);v=v-5;if(v<0) {printf("%d\n",v+5);continue;}memset(dp,0,sizeof(dp));for(i=0;i<n-1;i++){for(j=v;j-value[i]>=0;j--){dp[j]=max(dp[j],dp[j-value[i]]+value[i]);}}printf("%d\n",v-dp[v]+5-value[n-1]);}return 0;}</span></span>
HDU 1171
思路:
要均分价值,没法均分的话,尽量接近。问题可以理解成,从n个物品中,挑选出的物品价值和要尽量接近总价值一半。上述背包问题也可以理解为,装入的物品大小要尽量接近背包大小。本质一致。
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-size:18px;">#include<stdio.h>#include<string>int N;int dp[300000];//输出为,max(dp[V],sum-dp[V]),min(dp[V],sum-dp[V])int V;int value[5001];int max(int a,int b){return a>b?a:b;}int min(int a,int b){return a<b?a:b;}int main(){while(~scanf("%d",&N)&&N>=0){int sum=0,count=0;int i,j;for(i=0;i<N;i++){int a,b;scanf("%d%d",&a,&b);sum+=a*b;for(j=0;j<b;j++){value[count++]=a;}}V=(sum+1)/2;memset(dp,0,sizeof(dp));for(i=0;i<count;i++){for(j=V;j-value[i]>=0;j--){dp[j]=max(dp[j],dp[j-value[i]]+value[i]);}}printf("%d %d\n",max(dp[V],sum-dp[V]),min(dp[V],sum-dp[V]));}return 0;}</span></span>
HDU 2602
这题给出了物品的价值,要使得固定大小的背包装入物品的价值最大。很裸的背包问题。
代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="font-size:18px;">#include<stdio.h>#include<string>int T,N,V;int value[1001],cost[1001];int dp[1001];//输出为dp[V]int max(int a,int b){return a>b?a:b;}int main(){scanf("%d",&T);while(T--){scanf("%d%d",&N,&V);int i,j;for(i=0;i<N;i++){scanf("%d",&value[i]);}for(i=0;i<N;i++){scanf("%d",&cost[i]);}memset(dp,0,sizeof(dp));for(i=0;i<N;i++){for(j=V;j-cost[i]>=0;j--){dp[j]=max(dp[j],dp[j-cost[i]]+value[i]);}}printf("%d\n",dp[V]);}return 0;}</span></span>
HDU 2639
求第k个最优解,可以将数组多开一维,每次更新时用两个数组,一个存将物品放入背包的第k最优解,一个存不放入背包的第k最优解,再合并。
<span style="font-family:KaiTi_GB2312;font-size:18px;">#include<stdio.h>#include<string>int N,V,K;int value[101];int cost[101];int dp[1001][31];//输出dp[V][k]int A[32],B[32];int main(){int T;scanf("%d",&T);while(T--){scanf("%d%d%d",&N,&V,&K);int i,j,k;for(i=0;i<N;i++) scanf("%d",&value[i]);for(i=0;i<N;i++) scanf("%d",&cost[i]);memset(dp,0,sizeof(dp));for(i=0;i<N;i++){for(j=V;j-cost[i]>=0;j--){for(k=1;k<=K;k++){A[k]=dp[j-cost[i]][k]+value[i];//A存放入的第k大B[k]=dp[j][k];//B存不放入的第k大}//并入dp[j][k]int a1=1,b1=1;A[K+1]=B[K+1]=0;for(k=1;k<=K&&(A[a1]||B[b1]);){if(A[a1]>B[b1]) {if(A[a1]!=dp[j][k-1]){dp[j][k]=A[a1];k++;}a1++;}else{if(B[b1]!=dp[j][k-1]){dp[j][k]=B[b1];k++;}b1++;}}}}printf("%d\n",dp[V][K]);}return 0;}</span>
0 0
- 【01背包专题】--入门思考
- 【背包专题】01背包
- 【背包专题】01背包
- 01 背包 专题
- 01背包专题
- 01背包专题
- DP专题->01背包
- 背包入门--01背包
- 【背包专题——01背包】
- ~背包专题~01背包初体验
- 背包专题
- 背包专题
- 背包专题、
- 背包专题
- 01背包入门
- HDU 2602 01背包的思考
- 对01背包问题的思考
- 背包入门 01背包 hdu 2546
- 被颠倒的现实主义与理想主义(番外篇)
- 1602实现移屏功能
- 一切的一切
- 过程改进
- 凡是一切的都是起来
- 【01背包专题】--入门思考
- A breach beyond CRIME
- 服务器远程登录桌面,不小心logout的解决方法
- ASP程序密码验证漏洞
- android应用开发中获取amr文件的播放时间
- vs2012+qt5.2.0环境搭建
- 面向服务(Service)的架构
- 2014设计成就中国高峰论坛不容错过的N个理由
- MYSQL 时间问题