Fresh Meat
Description
我们故事的主角是屠夫扒鸡,起初屠夫扒鸡只是一个佣兵,他先去拜了太上老君为师,学了一技能肉钩,凭着一技肉钩驰骋决斗场,达到一段以后到阿尔伯特那里偷学了二技能肢解,这下可以连招了。后来因为太久没洗澡习得三技能腐烂。因为腐烂损人损己,扒鸡又懒得出回血装备,于是拜师蜘蛛,学了招极度饥渴,你懂的(不是字面上的意思) 。现在扒鸡自定义了个 RPG 要试试水了。RPG 地图介绍:地图上一共会出现 N 只英雄,每只英雄都有自己的生命值 Hi(不管什么英雄,扒鸡都是肉钩、腐烂、肢解一套带走) ,带走英雄的同时由于腐烂自己会损耗被杀死的英雄同等生命值的血量(提醒大家勤洗澡) ,一只英雄死后另一只英雄才会出现。扒鸡初始血量是 M,必要时可以开极度饥渴回血,一次只能吸一个英雄的血,腐烂效果还在,耗血Hi,但饥渴吸血量等于 Hi*2(相当于回复了 Hi 血量,血量没有上限,可以无限回复) ,啊~fresh meat~。扒鸡想知道自己最少要饥渴几次才能通关。注:血量小于等于 0 时将被带走。饥渴状态直接计算回血,忽略耗血
Input
第一行给出两个整数 N,M——要一套带走的英雄数量 N 和扒鸡的初始血量 M
接下来一行,给出 N 个英雄的血量 Hi(i∈1~N) ,英雄按照给出的顺序出现。
其中 0<N<=10000,0<=Hi<=10^9,1<=M<=10^9,
Output
输出一个整数,表示扒鸡最少需要饥渴的次数。
Sample Input
7 85 2 3 3 1 4 6
Sample Output
2
思路
要求需要的最少饥渴次数,我们可以换个角度,每杀死一个英雄,就获得一次使用饥渴技能的机会,那么每次在血量没有的时候,从杀死的英雄中选出血量值最多的英雄即可。
AC代码
#include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int maxn = 10005; struct Node { int val; bool flag; Node(): val(0), flag(false) { } bool operator < (const Node &a)const { return val < a.val; } } node[maxn]; int main() { //freopen("input.txt", "r", stdin); int N, M, i, res = 0; priority_queue<Node>que; scanf("%d%d", &N, &M); for (i = 0; i < N; i++) scanf("%d", &node[i].val); for (i = 0; i < N; i++) { if (M >= node[i].val) { M -= node[i].val; node[i].flag = true; que.push(node[i]); } else { node[i].flag = true; que.push(node[i]); while (M < node[i].val && !que.empty()) { Node tmp = que.top(); que.pop(); if (tmp.flag) { M += 2 * tmp.val; } else { M += tmp.val; } res++; } M -= node[i].val; } } printf("%d\n", res); return 0; }
时间: 2024-12-09 05:38:16