UVa 12325 - Zombie's Treasure Chest(暴力枚举+预处理)

来源:互联网 发布:php 数值 偏移量 编辑:程序博客网 时间:2024/04/29 16:33

给出背包大小n,两种宝物的体积s1、s2,两种宝物的价值v1、v2。求能装下的最大价值。

首先进行预处理,使n/s1的值尽可能小,满足O(n)的时间不超时。s2的宝物1与s1个宝物2体积相同,所以s=s1*s2的体积只会拿宝物s1或s2中的一种(当s2*v1>s1*v2时,只拿宝物1,反之亦然),这样就把n转化为n%s。然后为了使n/s1尽量小,当s1<s2时,交换s1、s2和v1、v2的值。

然后从零开始枚举需要拿的v1的个数,上限是n/s1,因为进行过预处理,所以保证不会超时。求出与处理之后的最大价值。

最后加上预处理拿到的价值x就是所求答案。

还要注意一点就是,s1、s2、v1、v2的值在int范围内,但相乘之后可能溢出,所以要使用long long。

#include<cstdio>#include<algorithm>using namespace std;int main(){    int k,t=0;    scanf("%d",&k);    while(k--){        long long n,s1,s2,v1,v2,x,best=0;        scanf("%lld%lld%lld%lld%lld",&n,&s1,&v1,&s2,&v2);        long long s=s1*s2,v=max(s2*v1,s1*v2);//求s=s1*s2时的最大价值v。        x=n/s*v;//预处理获得的价值。        n%=s;        if(s1<s2) swap(s1,s2),swap(v1,v2);        for(long long i=0;i<=n/s1;++i){            long long cur=0,m=n;            cur+=i*v1;            m-=i*s1;            cur+=m/s2*v2;            best=max(best,cur);//枚举维护最大价值。        }        best+=x;//二者相加。        printf("Case #%d: %lld\n",++t,best);    }    return 0;}


0 0
原创粉丝点击