背包问题
来源:互联网 发布:华夏银行贵金属软件 编辑:程序博客网 时间:2024/05/16 07:48
首先是0-1背包问题,这是最基本的背包问题,给定一个背包,容量为V,给定n个物品,并给出每个物品的体积和价值,每个物体只有一件。
下面是0-1背包问题的代码模型:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define Max 110#define Maxv 1010#define Maxx(a,b) (a)>(b)?(a):(b)int weight[Max];int value[Max];int dp[Maxv];int V;int n;int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d",&weight[i],&value[i]);memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++)for(int j=V;j>=weight[i];j--)dp[j]=Maxx(dp[j],dp[j-weight[i]]+value[i]); printf("%d\n",dp[V]);return 0;}
完全背包问题:
区别与0-1背包问题的关键点是:物体的个数是无穷,下面是代码模型:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define Max 110#define Maxv 1010#define Maxx(a,b) (a)>(b)?(a):(b)#define Inf 11111100int weight[Max];int value[Max];int dp[Maxv];int V;int n;int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d",&weight[i],&value[i]);memset(dp,0,sizeof(dp));//要求刚好装满//for(int i=1;i<=V;i++)//dp[i]=-Inf;//dp[0]=0;for(int i=1;i<=n;i++)for(int j=weight[i];j<=V;j++)dp[j]=Maxx(dp[j],dp[j-weight[i]]+value[i]);printf("%d\n",dp[V]);return 0;}
多重背包问题:
区别于0-1背包问题的关键在于物体的个数为num[i]下面是没有优化的代码模型
#include <stdio.h>#include <stdlib.h>#include <string.h>#define Max 110#define Maxv 1010#define Maxx(a,b) (a)>(b)?(a):(b)#define Inf 11111100int weight[Max];int value[Max];int num[Max];int dp[Maxv];int V;int n;int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d%d%d",&weight[i],&value[i],&num[i]);memset(dp,0,sizeof(dp));//要求刚好装满//for(int i=1;i<=V;i++)//dp[i]=-Inf;//dp[0]=0;for(int i=1;i<=n;i++)for(int k=0;k<=num[i];k++) for(int j=V;j>=weight[i];j--)dp[j]=Maxx(dp[j],dp[j-weight[i]]+value[i]);printf("%d\n",dp[V]);return 0;}
以hdu2191为例说明:
下面是优化代码一:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define Max(a,b) (a)>(b)?(a):(b)#define Maxv 110#define Maxx 20010int V,n,Case;int dp[Maxv];int weight[Maxx];int value[Maxx];int main(){ scanf("%d",&Case); while(Case--){ scanf("%d%d",&V,&n); memset(dp,0,sizeof(dp)); int pivot=0; int ww,vv,nn; for(int i=1;i<=n;i++){ scanf("%d%d%d",&ww,&vv,&nn); for(int j=1;j<nn;j<<=1){ weight[pivot]=j*ww; value[pivot++]=j*vv; nn-=j; } weight[pivot]=nn*ww; value[pivot++]=nn*vv; } for(int i=0;i<pivot;i++) for(int j=V;j>=weight[i];j--) dp[j]=Max(dp[j],dp[j-weight[i]]+value[i]); printf("%d\n",dp[V]); } return 0;}
下面是优化代码二:
#include <stdio.h>#include <stdlib.h>#include <string.h>#define Maxv 110#define Max(a,b) (a)>(b)?(a):(b)int dp[Maxv];int n,V,Case;int ww,vv,nn;void onepage(int weight,int value){ for(int i=V;i>=weight;i--) dp[i]=Max(dp[i],dp[i-weight]+value);}void compage(int weight,int value){ for(int i=weight;i<=V;i++) dp[i]=Max(dp[i],dp[i-weight]+value);}int main(){ scanf("%d",&Case); while(Case--){ scanf("%d%d",&V,&n); memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ scanf("%d%d%d",&ww,&vv,&nn); if(ww*nn>=V) compage(ww,vv); else{ for(int j=1;j<nn;j<<=1){ onepage(ww*j,vv*j); nn-=j; } onepage(nn*ww,nn*vv); } } printf("%d\n",dp[V]); } return 0;}
背包问题的核心是0-1背包问题的动态转移方程。dp[v]=max{dp[v],dp[v-weight]+value}
另外就是注意初始化问题。
0 0
- 【无限背包】背包问题
- 背包问题---01背包
- 背包问题--部分背包
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- 背包问题
- Job 提交&初始化
- Android GUI Widget RadioGroup
- 2014.7.20 最新 eclipse cdt 开发 c++ 11 配置教程
- Codeforces Round #257 (Div. 2)449A - Jzzhu and Chocolate
- asp.net 六大对象之Request、Response
- 背包问题
- javaweb+jasperreports报表+struts2
- 安卓开发什么时候使用jni
- STM32的断言机制——函数assert_param()
- UVA 10870 - Recurrences(矩阵快速幂)
- poj 1061 扩展欧几里得
- 练习题.实现简单的电子词典功能
- 通过PyDev zip安装Eclipse PyDev插件
- Windows平台下常用的串行通信串口编程API