[UvaLive 6757] Cup of Cowards [搜索]

17 篇文章 0 订阅
2 篇文章 0 订阅

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;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值