基础背包01(HDU2606,HUD3591)
来源:互联网 发布:sql是一种什么语言 编辑:程序博客网 时间:2024/06/06 00:18
背包,动态规划中一个很常见的类型。
有N 种物品和一个容量为V 的背包。放入第i 种物品耗费的费用是Ci,得到的价值是Wi。求解将哪些物品装入背包可使价值总和最大。
根据对于每种物品的数量要求,又可以将背包问题分为01背包(每种物品只有一个),完全背包(每种物品无限个),多重背包(每种物品特定数量个),分组背包(将物品分组,每组最多只有一个)等
接下来的两题,第一题是个简单01背包热身,第二题是个完全背包+多重背包的组合题
A.Bone Collector
思路:这是一道最基本的01背包问题,已知骨头价值和体积,装入特定体积背包,求最大价值。没有任何坑点,直接上手,算个热身。
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>using namespace std;const int maxn = 1e3+10;int w[maxn],p[maxn],f[maxn];int main(){ int t,n,v; while(scanf("%d",&t)!=EOF) { while(t--) { scanf("%d%d",&n,&v); for(int i=0;i<n;i++) { scanf("%d",&p[i]); } for(int i=0;i<n;i++) { scanf("%d",&w[i]); } memset(f,0,sizeof(f)); for(int i=0;i<n;i++) { for(int j=v;j>=w[i];j--) { f[j] = f[j] > (f[j-w[i]]+p[i]) ? f[j] : (f[j-w[i]]+p[i]); } } printf("%d\n",f[v]); } } return 0;}
J.The trouble of Xiaoqian
思路:这题相对于第一题,明显加深。但从购买者来看,是个多重背包问题,然而由于找零问题,似乎瞬间复杂了许多。然而,其实,如果将购买者和售货员分开看,售货员就是个完全背包问题,这道题就被转化为完全背包和多重背包两个包的组合问题,两包容量相差值即为货物总价值,最终求和即可。
对于多重背包问题,如果直接转化成背包,多达100+的物品数O(n)会直接TLE,于是考虑优化,对于物品总价值超出包容量的情况,可以直接转化为完全背包,否则,按2次指数分解可以将时间复杂度降到O(ln(n))。
最后注意一下这是个最小价值问题,注意一下初始化赋值就好了
#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>#include <climits>#include <cmath>using namespace std;const int maxn = 2e4+10;int v[110],c[110];int Xiaoqian[maxn],shopkeeper[maxn];//int pk[8] = {1,2,4,8,16,32,64,128};int main(){ int n,t,id = 0; while(scanf("%d%d",&n,&t)!=EOF) { id++; if(n==0&&t==0) { break; } for(int i=1;i<=n;i++) { scanf("%d",&v[i]); } for(int i=1;i<=n;i++) { scanf("%d",&c[i]); } for(int i=0;i<=maxn-5;i++) { Xiaoqian[i] = maxn; shopkeeper[i] = maxn; } Xiaoqian[0] = 0; shopkeeper[0] = 0; /*for(int i=1;i<=n;i++) { for(int k=0;k<=log2(c[i]);k++) { for(int j=maxn-5;j>=pk[k]*v[i];j--) { if(Xiaoqian[j]>Xiaoqian[j-pk[k]*v[i]] + pk[k]) { Xiaoqian[j] = Xiaoqian[j-pk[k]*v[i]] + pk[k]; } } } }*/ for(int i=1;i<=n;i++) { if(c[i] * v[i] > maxn - 10) { for(int j=v[i];j<=maxn-5;j++) { if(Xiaoqian[j]>Xiaoqian[j-v[i]] + 1) { Xiaoqian[j] = Xiaoqian[j-v[i]] + 1; } } } else { int k = 1; while(k<=c[i]) { for(int j=maxn - 5;j>=k * v[i];j--) { if(Xiaoqian[j]>Xiaoqian[j-k*v[i]] + k) { Xiaoqian[j] = Xiaoqian[j-k*v[i]] + k; } } c[i] -= k; k <<= 1; //cout << k << endl; } for(int j=maxn - 5;j>=c[i] * v[i];j--) { if(Xiaoqian[j]>Xiaoqian[j-c[i]*v[i]] + c[i]) { Xiaoqian[j] = Xiaoqian[j-c[i]*v[i]] + c[i]; } } } } for(int i=1;i<=n;i++) { for(int j=v[i];j<=maxn-5;j++) { if(shopkeeper[j]>shopkeeper[j-v[i]] + 1) { shopkeeper[j] = shopkeeper[j-v[i]] + 1; } } } int maxcoin = maxn; for(int i=t;i<=maxn-10;i++) { if(Xiaoqian[i] + shopkeeper[i-t] < maxcoin) { maxcoin = Xiaoqian[i] + shopkeeper[i-t]; } //cout << Xiaoqian[i] << "*"<<shopkeeper[i]<<endl; } if(maxcoin > maxn-10) { maxcoin = -1; } printf("Case %d: %d\n",id,maxcoin); } return 0;}
阅读全文
1 0
- 基础背包01(HDU2606,HUD3591)
- hdu2606
- hdu2602(01背包基础)
- HDU2602(基础01背包)
- #1038 : 01背包 ( 01 背包,基础DP)
- 51nod1085---背包问题(51nod基础:01背包)
- 01背包基础 (杭电2602)
- HDU 2546 饭卡 (基础01背包)
- 基础背包问题(01,完全,多重)
- 01 背包基础题目
- 01背包基础
- 基础01背包
- HDU2602-01背包基础
- 完全背包(基础)
- 01背包基础-1085 背包问题
- 背包问题(背包算法)(基础)
- hdu 2602 基础01背包
- 01背包基础详解(附求解选择的物品)
- bzoj1230[Usaco2008 Nov]lites 开关灯 线段树lazy标记
- mysql lock in share mode 和 select for update
- HDU1003 Max Sum【最大子段和+DP】
- 微信硬件平台
- 记hadoop集群黑名单移除节点出现问题及解决
- 基础背包01(HDU2606,HUD3591)
- java 用poi 生成表格合并单元格放法
- Intent的那些事儿
- 【jzoj5073】【GDOI2017第三轮模拟day1】【影魔】【数据结构】
- LeetCode 43 Multiply Strings
- D3添加title提示信息时出现滚动条时,显示错位的问题
- 使用RecycleView加载不同的布局(类似淘宝京东购物车+推荐商品列表)
- LeetCode -- 120. Triangle
- ACM题集以及各种总结大全!