UVA 12325 Zombie's Treasure Chest

题目链接:UVA12325

12325 - Zombie's Treasure Chest

Time limit: 3.000 seconds


数学题

第一眼以为是傻逼DP 然后发现数据量真大。。

后来想了一下 还是比较水的。

题意是给你两种物品 价值V1,V2  大小S1,S2 让你用一个大小是C的背包去装 

求最大价值。数据在int范围内(10^9数量级)

首先很容易想到如果比较大的背包的大于sqrt(C)的话  一定能在sqrt(C) 的复杂度内得到正解

因为可以枚举这个物品放多少个 最多sqrt(C) 个  

如果没有可以通过证明一个结论来搞  如果背包大小为 lcm(S1,S2) 那么一定是全装性价比最高的那种物品这个方案更优

这结论比较好证就不说了  然后通过这个结论  

可以得到一个枚举算法  先把所有背包用来装性价比高的那种物品  然后再用另一种物品替换  知道替换的容量超过lcm(S1,S2)就停止 

记录过程中的最大价值  就是最优解 

然后这种算法在  lcm(S1,S2) 比较大时  枚举次数会很多  


综合上面两个算法  就能解决这个问题了~

设S1>S2

如果 S1>50000   就用第一种算法来搞   即枚举大容量物品的个数  最多枚举C/S1次 (最坏10^4左右)

如果 S1<50000   就用第二种算法来搞   即枚举S2次替换  (最坏10^4左右)


#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;


int main()
{
//    freopen("1.txt","r",stdin);
    int t,ti=1;
    scanf("%d",&t);
    while(t--)
    {
        printf("Case #%d: ",ti++);
        long long c,c1,c2,v1,v2;
        scanf("%lld%lld%lld%lld%lld",&c,&c1,&v1,&c2,&v2);
        if(c1>c2) swap(c1,c2),swap(v1,v2);
        if(c2>50000)
        {
            long long ans=0;
            for(int i=0;i*c2<=c;i++)
                ans=max(ans,(c-i*c2)/c1*v1+i*v2);
            printf("%lld\n",ans);
        }
        else
        {
            if(v1*c2>v2*c1) swap(v1,v2),swap(c1,c2);
            long long ans=0;
            for(int i=0;i<=c2 && c-i*c1>=0;i++)
                ans=max(ans,(c-i*c1)/c2*v2+i*v1);
            printf("%lld\n",ans);
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值