您的位置:首页 > 其它

POJ 3465 Battle(优先队列+贪心模拟)

2017-08-13 19:09 405 查看
You're Zhu Rengong, a formidable hero. After a number of challenging missions, you are finally facing the final Boss – a black dragon called Heilong. Due to his overwhelming power, you have to plan your actions carefully.

You have H1 hit points (HP) at the beginning of the battle, and Heilong has H2. Heilong attacks you each time you do an action, and deal Ai points of damage in the i-th round. You have
three kinds of actions.

Attack. You attack Heilong, and do x points of damage.
Defend. You focus on avoiding the attack of Heilong. This action nullifies Heilong's attack in this round.
Heal. You heal yourself, adding y hit points to yourself. There is no upper bound on your HP.
If anyone's HP drop below or equal to 0, he dies. If you can't kill the dragon within N rounds, you will also die. So you need to know how many rounds you need to kill the black dragon. If you cannot kill him, you will have to calculate the maximal
damage you can do on Heilong.

Input

The first line contains five integers, N, x, y, H1, H2. 1 ≤ N ≤ 105, 1 ≤ x,y ≤ 104, 1 ≤ H1,H2 ≤ 109.
Then follow N lines, the ith line contains one integer Ai-1. 1 ≤ Ai-1 ≤ 104.

Output

If you can kill Heilong, the first line of your output should be "Win". Otherwise "Lose".

The second line contains the number of rounds you need to kill Heilong if the first line is "Win", or the maximal damage you can do if the first line is "Lose".

Sample Input
Sample Input 1
4 1 1 3 3
1
10
1
10
Sample Input 2
4 1 1000 1 4
1
10
1
1

Sample Output
Sample Output 1
Win
4
Sample Output 2
Lose
3

Hint
In Sample 1, you have to defend in the 2nd round, othewise you will die. 

In Sample 2, you heal yourself in the first round, and keep attacking until N rounds expires.

题解:

这题本来是很水的一题,比赛的时候由于老刘没仔细读题,也是我疏忽了看原题,导致做了很久,因为他读的是加血不能超过上限。。。。如果多了这个条件这题就会变得无比得蛋疼,要各种回溯各种状态改变,我想了半天一看别人的代码怎么那么短,仔细一读:”There is no upper bound on your HP.”吐血。。。。水爆了一次就a了

题意:

你是猪人拱,你要去打黑聋,那一排的数字分别是回合数,你的攻击力,你的回血能力,你的血量,黑聋的血量。然后一大条是每回合聋的攻击力,每回合你可以选择防御(类似于我爱罗的究极防御,不损一滴血,打个毛啊直接一直防饿死聋嘛,自己带个药水不就好了),攻击,回血,就是没有逃跑,问你n回合之前是否能干死黑聋,如果可以就输出几回合干死的,不能就输出你最多能打出多少伤害

思路:

没有血量上限就很水了嘛,直接用一个优先队列存之前聋的伤害,一开始就一直和它肛,如果死了就回到受伤害最高的那一回合根据情况选择回血还是防御(如果聋的攻击力比你的回血低就回嘛,防御就相当于回了聋攻击力的血了)

一开始就总想着有上限。。然后就用dfs写了,后来仔细读题后发现根本不用,哎懒得改了直接贴代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<string>
#include<stdio.h>
#include<queue>
#include<stack>
#include<map>
#include<deque>
#define M (t[k].l+t[k].r)/2
#define lson k*2
#define rson k*2+1
#define ll long long
#define INF 100861111;
using namespace std;
int a[100005];
priority_queue<int>q;//最大堆,大的先出
int h1,h2,heal,atc,tag,maxx;//分别表示你的最初hp,聋的最初hp,回血量和攻击力
void dfs(int index,int hp1,int hp2)
{
if(index>n)//如果到底了还没打死
{
tag=-1;
return;
}
int now;
now=a[index];
q.push(now);//更新当前伤害
if(tag!=0)//如果有结果了,0代表没结果,-1代表失败,其他代表最短回合数
return;
hp2-=atc;
hp1-=a[index];
if(hp2<=0)//聋被打死了
{
tag=index;
return;
}
if(h2-hp2>maxx)//更新最大伤害
maxx=h2-hp2;
if(hp1<=0)//你被打死了
{
while(hp1<=0&&!q.empty())//找前面是否可以防御或者回血可以杀死聋
{
now=q.top();
hp1+=max(now,heal);//利益最大化
hp2+=atc;
q.pop();
}
if(hp1<=0)//如果还是会死
{
tag=-1;
return;
}
}
dfs(index+1,hp1,hp2);//继续下一个。。可以直接写成循环不用dfs
}
int main()
{
int i,j;
scanf("%d%d%d%d%d",&n,&atc,&heal,&h1,&h2);
maxx=0;
tag=0;
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
dfs(1,h1,h2);
if(tag!=-1&&tag!=0)
{
printf("Win\n");
printf("%d\n",tag);
}
else
{
printf("Lose\n");
printf("%d\n",maxx);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: