Uva12325


/*

这道题是使用枚举的方法做,不能计算性价比(价值/体积),先安排尽量多的性价比高的物品。

因为,本题只能一次放整个物品,不能讲物品切割,放进去一部分,

比如,宝箱体积100,物品1,体积80,价值80,物品2,体积25,价值24

显然是物品1性价比更高,但是物品1只能放进去一个,物品2可以放进去4个,价值更多,因此还是使用枚举的放法。
这道题一个trick就是当s1和s2都很小的时候,首先计算s1和s2的最小公倍数s,s2*v1<s1*v2,那么最后的答案中物品1最多放置s2-1件,
因为如果放置s2或者更多的话,就可以把s2件物品1替换成s1件物品2,两种方法所占用体积是一样的,而后一种方法的价值更大,反之亦然。
这样就解决了当s1和s2都很小的时候,如何减少枚举次数的问题。
还有一个trick就是如何判断s1和s2是不是都是过小的,用N/s1或者N/s2和一个较大的常数比较,本题中选的是100500。
第三个trick就是所有整数选择long long int类型,否则会超时。
*/
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
 
 
int main()
{
    long long int T,N,s1,v1,s2,v2;
    scanf("%lld",&T);
    for(int i=1;i<=T;++i){
 
 
        scanf("%lld%lld%lld%lld%lld",&N,&s1,&v1,&s2,&v2);
        long long int ans=0;
        if(s1<s2){swap(s1,s2);swap(v1,v2);}
        if(s1*100500<N){
            if(s2*v1>s1*v2){swap(s1,s2);swap(v1,v2);}
            for(int i=0;i<s2/__gcd(s1,s2);++i)ans=max(ans,i*v1+(N-i*s1)/s2*v2);
        }else{
            for(int i=0;i*s1<=N;++i)ans=max(ans,i*v1+(N-i*s1)/s2*v2);
        }
        printf("Case #%d: %lld\n",i,ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/shihongliang1993/article/details/75004497