【贪心算法】19270:勇士斗恶龙

本文介绍了一道编程题目,涉及贪心算法的应用。小X需要利用n名勇士的攻击和生命值来杀死恶龙。勇士在战斗中受到的伤害会随着出场顺序增加,每名勇士造成的总伤害量需要最大化。通过计算每个勇士的总伤害量并排序,找到最有效的勇士组合以最少的人数击败恶龙。如果无法杀死恶龙,则输出'Fail'。
摘要由CSDN通过智能技术生成

【贪心算法】19270:勇士斗恶龙
题目描述
小 X 穿越到了异世界,国王命令他招揽勇士,杀死恶龙,救回公主。
异世界是高度数据化的。恶龙有一个攻击力 ATK,一个生命值 HP。类似的,每个勇士也有一个攻击力 Ai,一个生命值 Hi。
战斗是回合制的,并且每次只能由一个勇士和恶龙单挑。战斗中,每个回合恶龙的生命值会减去这个勇士的攻击力,这个勇士的生命值会减去恶龙的攻击力。
如果回合结束的时候恶龙的生命值小于等于 0,那么恶龙就被杀死了;如果这个勇士的生命值小于等于 0,那么这个勇士就被击败了,需要换上另一个勇士继续战斗。当然,如果恶龙还没有被杀死,勇士却全部被击败了,那么这场战役就彻底失败了。
不过聪明的小 X 安排了一个特殊的战术:在一名勇士被击败后立刻让另一名勇士发起攻击,这样恶龙在勇士们的车轮战术下疲于招架,受到第二个勇士的伤害变为两倍,受到第三个勇士的伤害变为三倍……以此类推。
现在一共有 n 名勇士报名,小 X 想问问你,如果合理安排勇士出战的顺序,最少要招揽多少名勇士才能杀死恶龙?
输入
第一行为一个正整数 n,表示一共有 n 名勇士报名。
第二行两个正整数 ATK 和 HP 表示恶龙的攻击力和生命值。
接下来共有 n 行,每行两个正整数 Ai 和 Hi 表示这名勇士的攻击力和生命值。
输出
输出一个整数,表示最少要招揽多少名勇士才能杀死恶龙。
如果不可能杀死恶龙,输出”Fail”。
样例输入
2
1 9
2 2
1 1
样例输出
2

提示
样例解释
两名勇士都招揽。先派出 2 号勇士
第一回合,恶龙生命值变为 8,勇士生命值变为 0。勇士被击败
紧接着派出 1 号勇士
第二回合,恶龙生命值变为 4(两倍伤害),勇士生命值变为 1
第三回合,恶龙生命值变为 0,勇士生命值变为 0。恶龙被杀死
勇士虽然也被击败了,但恶龙已经死了,所以还是胜利了!
数据范围
本题共有 10 个测试点,每个测试点 15 分
对于测试点 1-4 :n<=5,ATK,Hi,Ai<=10,HP<=100
对于测试点 5-7 :n<=1000,ATK,Hi,Ai<=1000,HP<=109
对于测试点 8-10 :n<=105,ATK,Hi,Ai<= 106,HP<=1018

题解
贪心算法的核心就是从局部最优解入手达到全局最优解。
本题中勇士具有血量和伤害两种属性,借鉴Knapsack算法,我们需要选出性价比高即总伤害量高的勇士。
选择方法:计算出每一个勇士的没有攻击加成的总伤害量(总伤害量=回合数*每一回合伤害)。考虑攻击加成,将总伤害量较高的勇士放在较后出场。

#include<iostream>
#include <algorithm>
typedef long long ll;
using namespace std;
const int MAX = 1e5;
ll n, k, atk, hp;
ll a[MAX];
int main() {
	cin >> n >> atk >> hp;		//输入勇士数,恶龙的伤害、血量
	for (int i = 0; i < n; i++) {
		ll aa, h;				//输入当前勇士的伤害、血量
		cin >> aa >> h;
		if (h % atk == 0)	k = h / atk;
		else				k = h / atk + 1;	//求出当前勇士的回合数
		a[i] = aa * k;		//算出总伤害量=回合数*每一回合伤害
	}
	sort(a, a + n);	//将各勇士按照总伤害量进行快排
	//寻找最优策略(从总伤害量最高的勇士依次往下寻找)
	for (int j = 1; j <= n; j++) {
		ll hpp = hp;
		for (int i = j, l = 1; i >= 1; i--, l++) {
			hpp -= a[n - i] * l;
			cout << hpp << endl;
		}
		if (hpp <= 0) {
			cout << j;
			return 0;
		}
	}
	cout << "Fail";
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值