BZOJ 3709: [PA2014]Bohater

题目

3709: [PA2014]Bohater

Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special Judge
Submit: 507  Solved: 163
[Submit][Status]

Description

在一款电脑游戏中,你需要打败n只怪物(从1到n编号)。为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值。任何时候你的生命值都不能降到0(或0以下)。请问是否存在一种打怪顺序,使得你可以打完这n只怪物而不死掉

Input

第一行两个整数n,z(1<=n,z<=100000),分别表示怪物的数量和你的初始生命值。
接下来n行,每行两个整数d[i],a[i](0<=d[i],a[i]<=100000)

Output

第一行为TAK(是)或NIE(否),表示是否存在这样的顺序。
如果第一行为TAK,则第二行为空格隔开的1~n的排列,表示合法的顺序。如果答案有很多,你可以输出其中任意一个。

Sample Input

3 5
3 1
4 8
8 3

Sample Output

TAK
2 3 1

题解

这道题目很明显是贪心,一开始直接去能回血的,而且很明显是从损失体力晓得开始回,这样可以保证在有解情况下能得到全部恢复。而,接下来的打怪阶段,我们可以看作一个回血的逆过程,把打怪过程倒过来看就和之前的回血一样了,所以是倒过来的贪心规则,则血药降序。然后模拟看看能不能打完就好!

代码

 1 /*Author:WNJXYK*/
 2 #include<cstdio>
 3 #include<iostream>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7
 8 const int Maxn=100000;
 9 struct Node{
10     long long r,d;
11     int index;
12 };
13 Node rec[Maxn+10],dam[Maxn+10];
14 int recs,dams;
15 long long n,z;
16
17 bool cmp1(Node a,Node b){
18     if (a.d<b.d) return true;
19     if (a.d==b.d && a.r>b.r) return true;
20     return false;
21 }
22
23 bool cmp2(Node a,Node b){
24     if (a.r>b.r) return true;
25     if (a.r==b.r && a.d<b.d) return true;
26     return false;
27 }
28
29 int main(){
30     scanf("%lld%lld",&n,&z);
31     for (int i=1;i<=n;i++){
32         long long reco,dama;
33         scanf("%lld%lld",&dama,&reco);
34         if (reco>=dama){
35             rec[++recs].r=reco;
36             rec[recs].d=dama;
37             rec[recs].index=i;
38         }else{
39             dam[++dams].r=reco;
40             dam[dams].d=dama;
41             dam[dams].index=i;
42         }
43     }
44     sort(rec+1,rec+1+recs,cmp1);
45     sort(dam+1,dam+1+dams,cmp2);
46     for (int i=1;i<=recs;i++){
47         if (z>rec[i].d){
48             z+=rec[i].r-rec[i].d;
49         }else{
50             printf("NIE\n");
51             return 0;
52         }
53     }
54     for (int i=1;i<=dams;i++){
55         if (z>dam[i].d){
56             z+=dam[i].r-dam[i].d;
57         }else{
58             printf("NIE\n");
59             return 0;
60         }
61     }
62     printf("TAK\n");
63     for (int i=1;i<=recs;i++) printf("%d ",rec[i].index);
64     for (int i=1;i<=dams;i++) printf("%d ",dam[i].index);
65     return 0;
66 }

时间: 2024-08-06 07:34:55

BZOJ 3709: [PA2014]Bohater的相关文章

【贪心】bzoj 3709:[PA2014]Bohater

3709: [PA2014]Bohater Time Limit: 5 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 653  Solved: 220[Submit][Status][Discuss] Description 在一款电脑游戏中,你需要打败n只怪物(从1到n编号).为了打败第i只怪物,你需要消耗d[i]点生命值,但怪物死后会掉落血药,使你恢复a[i]点生命值.任何时候你的生命值都不能降到0(或0以下).请问是否存在一种打怪顺序

bzoj 3709: [PA2014]Bohater 贪心

code: #include <bits/stdc++.h> #define N 100005 #define LL long long using namespace std; void setIO(string s) { string in=s+".in"; freopen(in.c_str(),"r",stdin); } struct data { LL a,d; int id; data(LL a=0,LL d=0,int id=0):a(a),

【BZOJ】3709: [PA2014]Bohater(贪心)

http://www.lydsy.com/JudgeOnline/problem.php?id=3709 很水的题...但是由于脑洞小..漏想了一种情况.. 首先显然能补血的先杀.. 然后杀完后从补血越多的杀..(这点我之前考虑错了QAQ) 正确性显然........ #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream>

3709: [PA2014]Bohater 贪心

傻傻的. 看到题目猜是贪心.结果只搞出了加血 > 减血的情况(很显然这种情况下把减血量从下到大排就可以了). 下面讲一下 减血 > 加血的,顺便给出我的证明. 对于这种情况,网上许多题解都是说把加血从大到下排就可以了.然而蒟蒻我还是不大明白,所以简单证了一下.如果错了,请指正. 设当前血量为 z, 存在i, j 使得 a[i] > a[j] 若先杀掉 j, 比先杀掉 i 优,(或者说存在先杀掉 j,后杀掉 i 能解决的情况而 先杀掉 i, 后杀掉 j 无法满足.) 那么 z - (d[i

[PA2014] [BZOJ 3709]~[BZOJ 3719] 合集

今天起尝试做套题喵~ (当然是因为被最大流的题目弄得恶心死了) 一共是 10 道题一道一道做 预计 3~4 内做完 尽情期待 [BZOJ 3709]Bohater 一眼就能感受到贪心的气息 因为很直观地,能加血的怪先打掉是不二法则 所以把怪分为两类: 能加血的和要掉血的 前者按伤害升序排序,算出最大血量 但后者要怎么搞让我很是郁闷~一开始是按伤害降序的,结果秒 WA 了 想想也是 Z=1000 怪1: a=998 d=1 怪2: a=100 d=99 你说先打哪只? 看来和回血量也是有关系的,事

BZOJ 3713: [PA2014]Iloczyn( 枚举 )

斐波那契数列<10^9的数很少很少...所以直接暴力枚举就行了... ------------------------------------------------------------- #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #define rep( i , n ) for( int i = 0 ; i < n ; ++i ) #d

BZOJ 3714: [PA2014]Kuglarz

呃..好像弃坑了好久=v=..本来打算在bzoj每刷10题合起来写一份题解..但是1个月好像还刷不到10题的样子(水题除外),所以还是单独写一下题解.. Description 魔术师的桌子上有n个杯子排成一行,编号为1,2,-,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品.花费c_ij元,魔术师就会告诉你杯子i,i+1,-,j底下藏有球的总数的奇偶性.采取最优的询问策略,你至少需要花费多少元,才能保证猜出哪些杯子底下藏着球? Input 第一行一个整数n(1<

bzoj3709 [PA2014]Bohater

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3709 [题解] 打完怪最后的体力是固定的,设为lst 我们考虑回血量>=扣血量的怪,这些肯定优先打,顺序肯定是按照扣血量从小到大打,这一定是最优策略,打不了就是NIE了 接着由于lst固定,我们考虑扣血量>回血量的怪,就相当于从lst开始 每次打一个怪吐出"回血量"这么多的血,增加"扣血量"这么多的血. 于是从后往前,就是按回血量从小到大打,依次判

bzoj 3714 [PA2014]Kuglarz 最小生成树

[PA2014]Kuglarz Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1335  Solved: 672[Submit][Status][Discuss] Description 魔术师的桌子上有n个杯子排成一行,编号为1,2,…,n,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品.花费c_ij元,魔术师就会告诉你杯子i,i+1,…,j底下藏有球的总数的奇偶性.采取最优的询问策略,你至少需要花费多少元,才能保证