【uva】12325 - Zombie's Treasure Chest

一开始以为是动规,后来发现不是,算是贪心吧。

思路:输入N,S1,V1,S2,V2,分别代表背包总容量,一号宝藏的体积和价格,二号宝藏的体积和价格。

那么 N / S1 和 N / S2 可以分别代表 N容量最多能装 一号,二号宝藏的数量,那么如果这2个数其中一个比较小的时候,如果N / S1 小 直接枚举一号宝藏的数量 进行 二号宝藏数量的计算,反之亦然。

但是还存在一个比较特殊的情况:如果N / S1 和 N / S2 都很大呢? 也就是说S1,S2都很小。

我们不妨假设下表:

                                                                                

  宝藏一 宝藏二
单位体积 S1 S2
单位价格 V1 V2
数量 S2 S1
总价格 S2*V1 S1*V2
总体积 S1*S2 S1*S2

我们不妨设一号宝藏有S2个,二号宝藏有S1个,那么一号宝藏总体积和二号宝藏总体积就一样了,如果S2 *V1 > S1 * V2的话,说明宝藏二的数量肯定在[0,S1)内,因为

如果体积大于了S1,那么,宝藏二的总价格 就为 S * V2(S > S1),那么肯定体积就大于S1*S2了,S1*S2的体积下,拿宝藏二肯定不如拿宝藏一。


以上就是分析,还有一个比较坑人的地方就是由于输入为32位,所以需要使用Long Long 否则会被后台数据卡死的(亲身经历~ TAT)

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<stack>
#include<queue>
#include<map>
#include<vector>
typedef long long LL;
using namespace std;
LL n,V1,S1,V2,S2;
#define INF 5000
LL solve(int choice){
    LL MAX = -1;
    if(choice == 0){
        for(LL i = 0 ; i * S1 <= n ; i++){
            LL temp = n - i * S1;
            LL ans  = temp / S2 * V2 + i * V1;
            MAX = max(MAX,ans);
        }
    }
    else if(choice == 1){
        for(LL i = 0 ; i * S2 <= n ; i++){
            LL temp = n - i * S2;
            LL ans  = temp / S1 * V1 + i * V2;
            MAX = max(MAX,ans);
        }
    }
    else {
        LL Sum1 = S2 * V1;
        LL Sum2 = S1 * V2;
        if(Sum1 > Sum2){
            for(LL i = 0 ; i < S1 ; i++){
                LL temp = n - i * S2;
                LL ans  = temp / S1 * V1 + i * V2;
                MAX = max(MAX,ans);
            }
        }
        else {
            for(LL i = 0 ; i < S2 ; i++){
                LL temp = n - i * S1;
                LL ans  = temp / S2 * V2 + i * V1;
                MAX = max(MAX,ans);
            }
        }
    }
    return MAX;
}
int main(){
    int T,Case = 1;
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld%lld%lld%lld",&n,&S1,&V1,&S2,&V2);
        /*分别输入宝物一和宝物二的体积 价值*/
        LL ans;
        if((n / S1) < INF)
            ans = solve(0);
        else if((n / S2) < INF)
            ans = solve(1);
        else {
            ans = solve(2);
        }
        printf("Case #%d: %lld\n",Case ++, ans);
    }
    return 0;
}


你可能感兴趣的:(【uva】12325 - Zombie's Treasure Chest)