您的位置:首页 > 其它

UVA 12325 Zombie'sTreasureChest 宝箱 (分类枚举)

2015-07-10 19:38 162 查看
看上去非常像背包的问题,但是体积太大了。

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

宝物有两种体积为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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: