[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;
}  
 
 



来自为知笔记(Wiz)



posted on 2016-02-28 15:05  红洋  阅读(213)  评论(2)    收藏  举报

导航