码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 12325 Zombie'sTreasureChest

时间:2015-07-10 20:44:40      阅读:215      评论:0      收藏:0      [点我收藏+]

标签:

看上去非常像背包的问题,但是体积太大了。

线性规划的知识,枚举附近点就行了,优先选性价比高的,

宝物有两种体积为S0,价值V0,体积S1,价值V1。

枚举分以下几种:

1:枚举拿宝物1的数量,然后尽量多拿宝物2;O(N/S0)

2:枚举拿宝物2的数量,同上;O(N/S1)

3.贪心,尽量选性价比高的

令gcd(S0,S1)= t,S1/t*S0 = S0/t*S1;体积相同的情况下尽量选价值高的,如果S1*V0>S0*V1大,那么枚举拿宝物2的数量,最多S0/t-1个否则一定可以换成S1/t个宝物1。反之亦然。O(max{S0/t,S1/t})

提前判断选择枚举量最小的即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

ll GCD(ll a,ll b){
    return b?GCD(b,a%b):a;
}

int main()
{
 //   freopen("in.txt","r",stdin);
    int T;
    ll S[2];
    ll V[2];
    ll n;
    scanf("%d",&T);
    for(int cas = 1; cas <= T; cas++){
        scanf("%lld%lld%lld%lld%lld",&n,S,V,S+1,V+1);
        bool flag0 = S[1]*V[0] > S[0]*V[1];
        ll gcd = GCD(S[1],S[0]);
        ll t = (flag0? S[0]/gcd : S[1]/gcd )-1;
        ll a[3] = {n/S[0],n/S[1],t};
        ll Value = 0;
        int flag = min_element(a,a+3)-a;
        int M = t;
        if(flag <= 1) {
            if(flag == 1) {swap(*S,S[1]); swap(*V,V[1]); M = a[1];}
            else M = *a;
        }else if(flag0) {swap(*S,S[1]); swap(*V,V[1]);}

        //枚举拿宝物0的数量
        for(int i = 0; i <= M; i++){
            int j = (n-S[0]*i)/S[1];
            ll val = i*V[0] + j*V[1];
            Value = max(Value,val);
        }
        printf("Case #%d: %lld\n",cas,Value);
    }
    return 0;
}

 

UVA 12325 Zombie'sTreasureChest

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4637101.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!