SPOJ 181 - Scuba diver 二维背包
潜水员要潜水,给出n个气缸(1<=n<=1000),每个气缸中有氧气量为ti,氮气量为ai,气缸重量为wi(1<=ti<=21,1<=ai<=79,1<=wi<=800)。现在潜水员需要量为t的氧气,量为a的氮气(1<=t<=21,1<=a<=79),问选哪些气缸,使得重量最小。
【背包】二维背包问题,不同的是这个要选的物品占两种容量至少为t和a。
设dp[i][j][k]为氧气量为j,氮气量为k时的最小重量
dp[i][j][k]=min{ dp [ i-1 ] [ j-t[i] ] [ k-a[i] ] + w[i] }
显然第一维可以在用循环覆盖省略掉
一开始我这样是这样写的
- for (i=;i<=m;i++)
- {
- for (j=ti;j>=;j--)
- {
- for (k=ai;k>=;k--)
- {
- if (dp[j+t[i]][k+a[i]]>dp[j][k]+w[i])
- {
- dp[j+t[i]][k+a[i]]=dp[j][k]+w[i];
- if (j+t[i]>=ti && k+a[i]>=ai) ans=min(ans,dp[j+t[i]][k+a[i]]);
- }
- }
- }
- }
然后就WA了,一开始怎么也找不到错误,后来发现是循环边界有问题,假如数据
显然答案是三个全部都用上,
当扫描到第三个物品时,j必须是2,才能假如该物品,但是代码中j不可能取到2,这里发生了错误。
更好的办法就是当j+t[i]>ti时一律将j+t[i]视为ti,k+a[i]视为ai。
- for (i=;i<=m;i++)
- {
- for (j=ti;j>=;j--)
- {
- for (k=ai;k>=;k--)
- {
- x=j+t[i];if (x>ti) x=ti;
- y=k+a[i];if (y>ai) y=ai;
- if (dp[x][y]>dp[j][k]+w[i])
- {
- dp[x][y]=dp[j][k]+w[i];
- }
- }
- }
- }
完整代码:
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<iostream>
- #include<algorithm>
- #include<set>
- #include<map>
- #include<stack>
- #include<vector>
- #include<queue>
- #include<string>
- #include<sstream>
- #define eps 1e-9
- #define ALL(x) x.begin(),x.end()
- #define INS(x) inserter(x,x.begin())
- #define FOR(i,j,k) for(int i=j;i<=k;i++)
- #define MAXN 1005
- #define MAXM 40005
- #define INF 0x3fffffff
- using namespace std;
- typedef long long LL;
- int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
- bool flag;
- int ti,ai,t[],a[],w[],dp[][];
- int main()
- {
- scanf("%d",&T);
- while (T--)
- {
- scanf("%d%d",&ti,&ai);
- scanf("%d",&m);
- for (i=;i<=m;i++)
- {
- scanf("%d%d%d",&t[i],&a[i],&w[i]);
- }
- memset(dp,0x2f,sizeof(dp));
- dp[][]=;
- ans=INF;
- for (i=;i<=m;i++)
- {
- for (j=ti;j>=;j--)
- {
- for (k=ai;k>=;k--)
- {
- x=j+t[i];
- y=k+a[i];
- if (x>ti) x=ti;
- if (y>ai) y=ai;
- if (dp[x][y]>dp[j][k]+w[i])
- {
- dp[x][y]=dp[j][k]+w[i];
- }
- }
- }
- }
- printf("%d\n",dp[ti][ai]);
- }
- return ;
- }
SPOJ 181 - Scuba diver 二维背包的更多相关文章
- 二维背包(钟神想要的)(不是DP)
[问题描述] 背包是个好东西,希望我也有.给你一个二维的背包,它的体积是? × ?.现在你有一些大小为1× 2和1×3的物品,每个物品有自己的价值.你希望往背包里面装一些物品,使得它们的价值和最大,问 ...
- hdu 4501 小明系列故事——买年货_二维背包
题目:你可以有v1元,v2代金券,v3个物品免单,现在有n个商品,商品能用纸币或者代金券购买,当然你可以买v3个商品免费.问怎么最大能买多少价值 题意: 思路二维背包,dp[v1][v2][v3]=M ...
- HDU 2159 FATE (二维背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159 解题报告:这题实际上是一个二维的背包问题,也可以由01背包扩展而来,01背包用一维数组,可想而知 ...
- rqnoj-329-刘翔!加油!-二维背包
注意排除干扰项. 因为价值不会相等,所以价值的多少与本题没有任何关系,. 所以价值为干扰项,所以不用考虑. 二维背包,简单求解. #include<stdio.h> #include< ...
- NOI 4978 宠物小精灵之收服(二维背包)
http://noi.openjudge.cn/ch0206/4978/ 描述 宠物小精灵是一部讲述小智和他的搭档皮卡丘一起冒险的故事. 一天,小智和皮卡丘来到了小精灵狩猎场,里面有很多珍贵的野生宠物 ...
- dp之二维背包poj2576
题意:有一群sb要拔河,把这群sb分为两拨,两拨sb数只差不能大于1,输出这两拨人的体重,小的在前面...... 思路:把总人数除2,总重量除2,之后你会发现就是个简单的二维背包,有两个限制..... ...
- hdu 3496 Watch The Movie (二维背包)
Watch The Movie Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- 二维背包---P1509 找啊找啊找GF
P1509 找啊找啊找GF 题解 很明显这是一道二维背包题目 如果一个dp数组做不了,那么我们就再来一个dp数组 题目要求,花费不超过 m ,消耗人品不超过 r ,泡到尽量多的妹子,时间尽量少 f ...
- 二维背包---P1855 榨取kkksc03
P1855 榨取kkksc03 题解 二维背包板子题 f[ i ][ j ] 前 n 个物品,花费金钱不超过 i ,花费时间不超过 j 的最大价值 如果每个物品只能选一次,那么就相当于在01背包上多加 ...
随机推荐
- python unicode&str 转化
从数据库中取出的值是Unicode编码的 需要转化为str才能正常使用 参考: http://www.mamicode.com/info-detail-308445.html
- Python爬虫第一步
这只是记录一下自己学习爬虫的过程,可能少了些章法.我使用过的是Python3.x版本,IDE为Pycharm. 这里贴出代码集合,这一份代码也是以防自己以后忘记了什么,方便查阅. import req ...
- CodeChef FNCS
题面:https://www.codechef.com/problems/FNCS 题解: 我们考虑对 n 个函数进行分块,设块的大小为S. 每个块内我们维护当前其所有函数值的和,以及数组中每个元素对 ...
- Js Framework
http://www.mhtml5.com/2012/06/5119.html http://www.mhtml5.com/2012/06/5118.html http://cubiq.org/isc ...
- Gnome Tetravex
zoj1008:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1008 题目意思是有一个游戏,即给出一个图,该图是由n*n个 ...
- BZOJ 1030 [JSOI2007]文本生成器
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2624 Solved: 1087[Submit][Stat ...
- CH Round #48 - Streaming #3 (NOIP模拟赛Day1)
A.数三角形 题目:http://www.contesthunter.org/contest/CH%20Round%20%2348%20-%20Streaming%20%233%20(NOIP模拟赛D ...
- -_-#【CSS3】CSS3 gradient transition with background-position
CSS3 gradient transition with background-position <!DOCTYPE html> <html> <head> &l ...
- voronoi
- 2012蓝桥杯本科组C/C++预赛题
微生物增殖 假设有两种微生物 X 和 Y X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍). 一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y. ...