HDU-4091 Zombie’s Treasure Chest

HDU-4091
题意:T次输入,每次输入背包容量n,绿宝石体积s1,价值v1,蓝宝石体积s2,价值v2,宝石无限,问背包的最大价值。
思路:因为数据可以很大,所以不能用完全背包求。两个物品,想到贪心,将性价比高的优先放入背包;但由于背包容量限制,还需要枚举减少性价比高的物品,加入性价比低的物品,也许能增大背包价值。
我们知道,对于体积是m=lcm(s1,s2)背包,肯定全选性价比高的。所以至多只要枚举n-n/m+m的体积。其余肯定用性价比高的放置。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<math.h>
#include<algorithm>

using namespace std;
#define LL __int64

LL gcd(LL a, LL b)
{
    if(a > b) swap(a,b);
    return a==0 ? b : gcd(b%a,a);
}

LL lcm(LL a, LL b)
{
    return b/gcd(a,b)*a;
}

int main()
{
    int T;
    LL n, s1, s2, v1, v2;
    scanf("%d",&T);
    for(int j = 1; j <= T; j++)
    {
        cin >> n >> s1 >> v1 >> s2 >> v2;
        LL m = lcm(s1,s2);
        LL k = n/m;
        if(k) k--;
        LL ans = 0;
        n = n - k*m; //需要枚举的空间
        if(s1 < s2) //让1号物品是体积大的那个,便于后面枚举
        {
            swap(v1,v2);
            swap(s1,s2);
        }
        for(LL a = 0; a*s1 <= n; a++)//枚举体积大的物品数量
        {
            ans = max(ans, a*v1+(n-s1*a)/s2*v2);
        }
        if(v1*s2 < v2*s1) //让1号物品是性价比高的那个,为了后面计算
        {
            swap(v1,v2);
            swap(s1,s2);
        }
        ans += k*(m/s1)*v1;
        printf("Case #%d: %I64d\n",j,ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值