1. 程式人生 > >bzoj3709 [PA2014]Bohater

bzoj3709 [PA2014]Bohater

amp signed include 這一 for ref mes clu lose

傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=3709

【題解】

打完怪最後的體力是固定的,設為lst

我們考慮回血量>=扣血量的怪,這些肯定優先打,順序肯定是按照扣血量從小到大打,這一定是最優策略,打不了就是NIE了

接著由於lst固定,我們考慮扣血量>回血量的怪,就相當於從lst開始

每次打一個怪吐出“回血量”這麽多的血,增加“扣血量”這麽多的血。

於是從後往前,就是按回血量從小到大打,依次判斷即可。

技術分享
# include <set>
# include <stdio.h>
# include <string
.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e5 + 10; const int mod = 1e9+7; # define RG register # define ST static int n; ll cur, lst;
struct pa { int d, a, id; pa() {} pa(int d, int a, int id) : d(d), a(a), id(id) {} }p[M], q[M]; int pn = 0, qn = 0; inline bool cmp(pa a, pa b) { return a.d < b.d; } inline bool cmp2(pa a, pa b) { return a.a < b.a; } int main() { cin >> n >> cur; lst = cur;
for (int i=1, D, A, C; i<=n; ++i) { scanf("%d%d", &D, &A); C = A-D; lst += C; if(C >= 0) p[++pn] = pa(D, A, i); else q[++qn] = pa(D, A, i); } sort(p+1, p+pn+1, cmp); sort(q+1, q+qn+1, cmp2); for (int i=1; i<=pn; ++i) if(cur <= p[i].d) { puts("NIE"); return 0; } else cur = cur - p[i].d + p[i].a; for (int i=1; i<=qn; ++i) if(lst <= q[i].a) { puts("NIE"); return 0; } else lst = lst - q[i].a + q[i].d; puts("TAK"); for (int i=1; i<=pn; ++i) printf("%d ", p[i].id); for (int i=qn; i; --i) printf("%d ", q[i].id); return 0; }
View Code

bzoj3709 [PA2014]Bohater