Zombie‘s Treasure Chest(UVA - 12325)

网址如下:

Zombie's Treasure Chest - UVA 12325 - Virtual Judge (vjudge.net)

一道枚举题

先上代码:

#include<cstdio>
#include<algorithm>

typedef long long LL;

LL N, S[2], V[2], ans;

void get_ans(int id1, LL end){
    ans = 0;
    int id2 = id1 ? 0 : 1;
    for(LL n1 = 0; n1 <= end; n1++){
        LL n2 = (N - n1 * S[id1]) / S[id2];
        LL _V = n1 * V[id1] + n2 * V[id2];
        ans = ans > _V ? ans : _V;
    }
}

int main(void)
{
    int T; scanf("%d", &T);
    for(int i = 1; i <= T; i++){
        scanf("%lld%lld%lld%lld%lld", &N, &S[0], &V[0], &S[1], &V[1]);
        LL end, id, e1 = N / S[0], e2 = N / S[1];
        id = e1 > e2; end = e1 < e2 ? e1 : e2;

        LL LCM = S[0] * S[1] / std::__gcd(S[0], S[1]);
        e1 = LCM / S[0]; e2 = LCM / S[1];
        int t_id = V[0] * S[1] > V[1] * S[0];
        LL e0 = LCM / S[t_id] - 1;
        if(e0 < end){end = e0; id = t_id;}
        get_ans(id, end);
        printf("Case #%d: %lld\n", i, ans);
    }

    return 0;
}

同样可以解出来的代码:

#include<cstdio>
#include<algorithm>

typedef long long LL;

LL N, S1, V1, S2, V2, LCM, ans;

int main(void)
{
    int T; scanf("%d", &T);
    for(int i = 1; i <= T; i++){
        ans = 0;
        scanf("%lld%lld%lld%lld%lld", &N, &S1, &V1, &S2, &V2);
        if(S1 < S2){
            V1 ^= V2 ^= V1 ^= V2;
            S1 ^= S2 ^= S1 ^= S2;
        }
        LCM = S1 * S2 / std::__gcd(S1, S2);
        LL beg, end;
        if(V1 * S2 > V2 * S1){
            beg = (N - LCM) / S1; beg = beg < 0 ? 0 : beg;
            end = N / S1;
        }
        else{
            beg = 0;
            end = LCM / S1 - 1; end = end < 0 ? 0 : end;
            end = end < (N / S1) ? end : (N / S1);
        }
        for(LL n1 = beg; n1 <= end; n1++){
            LL n2 = (N - n1 * S1) / S2;
            LL V = V1 * n1 + V2 * n2;
            ans = ans > V ? ans : V;
        }
        printf("Case #%d: %lld\n", i, ans);
    }
}

这两代码的原理是一样的,就是第二个代码在转化的时候出问题了,害的我改了好久

原理:

关键在于减少枚举量,若枚举宝物1的数量,则枚举量为N / S1;枚举宝物2的则是N / S2

求出S1和S2的最小公倍数LCM,即当二者的体积相同的时候,若宝物1的价值更大,则宝物2拿的数量不能超过LCM / S2,因为若超过,LCM大小的体积部分完全可以替换为宝物1,且价值更大。反之,可以推出宝物2的价值更大的情况

根据这个原理,就可以写出代码了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值