[2016-02-28][UVA][12325][Zombie's Treasure Chest]
- 时间:2016-02-28 10:12:22 星期日
- 题目编号:UVA 12325
- 题目大意:给出两个宝物的大小和价值,和容器的容量,求容器内最多能放多大价值的宝物
- 输入:
- cntcase
- n s1 v1 s2 v2
- ...
- 输出:Case #curcase: maxvalue\n
- 分析:
- 完全背包问题,但是容器的范围是32-bit int范围,很大,所以放弃dp?
- 宝物只有两种,那么可以用枚举的方法:
- 如果宝物体积相同,那么就选择价值大的物品
- 如果宝物体积不一样,有3种枚举方法
- 枚举宝物1的时候,尽可能多拿宝物2,时间复杂度为 O(n/s1)
- 枚举宝物2的时候,尽可能多拿宝物1,时间复杂度为 O(n/s2)
- 所以,选择两者时间小的进行枚举
- 但是,如果O(n/s1) 和 O(n/s1) 很大的话,会T,(n取maxint,而s取1 o(︶︿︶)o )
- 选性价比高的(单位体积价值高的),那么就枚举性价比低的物品的个数(性价比低的最多取s - 1个)
- 假设 v1 / s1 > v2 / s2 ----> v1 * s2 > v2 * s1
- 那么如果v2取了 s1个,那么必有 v1取s2个的价值更大,所以v2最多取到s1 - 1个
- 此时,消耗的空间都是 s1*s2
- 解题过程遇到问题:
- 先装满性价比高的,剩下再装另外一个,这种策略得到的答案不一定是最优的,
|
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
typedef long long LL;
#define CLR(x,y) memset((x),(y),sizeof((x)))
#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))
#define FORD(x,y,z) for(int (x)=(y);(x)>=(z);--(x))
#define FOR2(x,y,z) for((x)=(y);(x)<(z);++(x))
#define FORD2(x,y,z) for((x)=(y);(x)>=(z);--(x))
LL n,s[2],v[2];
LL solve(){
/*if(s[0] == s[1]){
return n / s[0] * max(v[0],v[1]);
}//可有可无*/
//计算时间复杂度
LL o1 = max(s[0],s[1]),o2 = n / o1;
if(o1 < o2){
LL v1 = v[0]*s[1],v2 = v[1]*s[0];
//保证第一个物品的性价比最大
if(v1 < v2){
swap(s[0],s[1]);
swap(v[0],v[1]);
}
LL maxvalue = 0;
for(LL i = 0;i < s[0] && i*s[0] < n;++i){//枚举 v[1]的数量
LL j = (n - i * s[1])/s[0];//计算v[0]的数量
if(j < 0) break;
maxvalue = max(maxvalue,i*v[1]+(j < 0?0:j)*v[0]);
}
return maxvalue;
}else{
//保证s[0]是大的
if(s[1] > s[0]){
swap(s[0],s[1]);
swap(v[0],v[1]);
}
LL maxvalue = 0;
for(LL i = 0;i*s[0] < n;++i){//枚举s[0]的数量
LL j = (n - i * s[0])/s[1];//计算s[1]的数量
maxvalue = max(maxvalue,i*v[0]+(j < 0?0:j)*v[1]);
}
return maxvalue;
}
}
int main(){
/* freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);*/
int cntcase;
scanf("%d",&cntcase);
FOR(curcase,1,cntcase + 1){
scanf("%lld%lld%lld%lld%lld",&n,&s[0],&v[0],&s[1],&v[1]);
printf("Case #%d: %lld\n",curcase,solve());
}
return 0;
} |
浙公网安备 33010602011771号