UVa #12325 Zombie's Treasure Chest (例题7-11)

86 篇文章 0 订阅

书中的分类枚举法一举克服了普通枚举最大10^9的规模:


第一种宝藏最多n/s1个,所以宝藏1的数量可以从1枚举到n/s1,同时算出宝藏2最多多少个,求出总价值。

宝藏2最多n/s1个,枚举方法同上。

因此如果n/s1比较小,就枚举宝藏1,n/s2比较小就枚举宝藏2


如果n很大而s1 s2很小,则用以下的枚举法:

s2个宝藏1和s1个宝藏2体积相等,但价值分别为s2*v1和s1*v2。如果前者大于后者,则最优解的宝藏2最多拿s1-1个,因为如果拿了s1个宝藏2,则可以全部换成宝藏1,体积一样但价值更高了。反之对于宝藏1也一样。因此枚举量最大为max(s1-1, s2-1)。


一个坑是整型溢出。


Run Time: 0.025s

#define UVa  "LT7-11.12325.cpp"		//Zombie's Treasure Chest
char fileIn[30] = UVa, fileOut[30] = UVa;

#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

//Global Variables. Reset upon Each Case!
int T;
long long n, s1, v1, s2, v2;
/

int main() {
    scanf("%d", &T);
    for(int kase = 1; kase <= T; kase ++) {
        scanf("%lld%lld%lld%lld%lld", &n, &s1, &v1, &s2, &v2);
        long long q1 = n/s1, q2 = n/s2, q3 = max(s1, s2);
        long long mincomplex = min(min(q1, q2), q3);
        long long maxv = 0, v = 0;
        if(mincomplex == q1) {
            for(long long i = 0; i <= n/s1; i ++) {
                v = i*v1 + ((n-(i*s1))/s2)*v2;
                maxv = max(maxv, v);
            }
        }
        else if (mincomplex == q2) {
            for(long long i = 0; i <= n/s2; i ++) {
                v = i*v2 + ((n-(i*s2))/s1)*v1;
                maxv = max(maxv, v);
            }
        }
        else {
            long long a = s1*v2, b = s2*v1;
            if(a > b) {
                for(long long i = 0; i <= s2 - 1; i ++) {      //# of treasury 1.
                    v = i*v1 + ((n-(i*s1))/s2)*v2;
                    maxv = max(maxv, v);
                }
            }
            else {
                for(long long i = 0; i <= s1 - 1; i ++) {      //# of treasury 2.
                    v = i*v2 + ((n-(i*s2))/s1)*v1;
                    maxv = max(maxv, v);
                }
            }
        }
        printf("Case #%d: %lld\n", kase, maxv);
    }
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值