您的位置:首页 > 其它

[UvaLive 6757] Cup of Cowards [搜索]

2014-07-20 14:16 211 查看
Root ::Regionals
2013 ::
Africa/Middle East - Arab Contest 6757 - Cup of Cowards

现有5个人打一个怪物,怪物的血量为10^12,每个人每次攻击有会令怪物掉一定的血量,同时会产生一定的费用,并且每个人都有一个攻击次数上限,问击败怪物的最少花费。若花费相同,则要求对怪物的伤害溢出最小

这个问题其实是一个5个物品的多重背包问题,但是由于背包容量太大(10^12),所以无法dp做。

于是直接搜索,加一些优化。

1. 先尝试性价比高的人,即攻击力高费用低的人

2. 若剩下的所有人的所有攻击均不能将boss打死,则不继续搜索

3. 若剩下的性价比最高的人的攻击次数不设限制且可以为小数,恰好打死boss的花费都比当前解差,则不继续搜索

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

struct Peo {
int h;
long long d,c;
friend bool operator < (const Peo &a,const Peo &b) {
if (a.d*b.c!=b.d*a.c) return a.d*b.c>b.d*a.c;
return a.c<b.c;
}
};

long long l;
Peo a[5];
long long maxdam[5];
long long cost,dam;

void dfs(int i,long long curcos,long long curdam) {
//printf("--%d %lld %lld\n",i,curcos,curdam);
if (curdam>=l) {
if (cost==-1||curcos<cost) {
cost=curcos;
dam=curdam;
} else if (curcos==cost&&curdam<dam) {
dam=curdam;
}
return;
}
if (i>=5) return;
if (maxdam[i]+curdam<l) return;
long long k=l-curdam;
k=k/a[i].d+(k%a[i].d!=0);
if (cost!=-1&&(k-1)*a[i].c+curcos>cost) return;
if (k>a[i].h) k=a[i].h;
for (int j=k;j>=0;j--) {
dfs(i+1,curcos+j*a[i].c,curdam+j*a[i].d);
}
}

int main() {
int t,i;
scanf("%d",&t);
while (t--) {
scanf("%lld",&l);
for (i=0;i<5;i++) scanf("%d%lld%lld",&a[i].h,&a[i].d,&a[i].c);
sort(a,a+5);
//for (i=0;i<5;i++) printf("%d %lld %lld\n",a[i].h,a[i].d,a[i].c);
maxdam[4]=a[4].d*a[4].h;
for (i=3;i>=0;i--) maxdam[i]=a[i].d*a[i].h+maxdam[i+1];
cost=-1;dam=-1;
dfs(0,0,0);
if (cost==-1) printf("We are doomed!!\n");
else printf("%lld %lld\n",cost,dam);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: