每次打代码的时候都很开心,打完就觉得自己好狗怎么办。
题意:
要逃出金字塔,金字塔里有n个陷阱,解开每一个陷阱需要ti的时间,也可以不解开陷阱直接通过,那样会损失1点hp,初始hp为k,hp为0时死亡。如果在di时刻之后还没有通过第i个陷阱,怪兽就会把你吃掉。求最少损失多少点hp能逃出去,如果逃不出去,输出-1.
Input
There are multiple test cases (no more than 20).
For each test case, the first line contains two integers N and K (1 <= N <= 25000, 1 <= K <= 5000), then followed by N lines, the ith line contains two integers Ti and Di (0 <= Ti <= 10^9, 0 <= Di <= 10^9).
Output
For each test case, if they can escape from the pyramid, output the minimal HP cost, otherwise output -1.
Sample Input
3 2 40 60 60 90 80 120 2 1 30 120 60 40
Sample Output
1 -1
这题和之前做过的一个加油的题十分类似的贪心。
先把所有陷阱按照di排序,di前必须通过陷阱i,用sum维护现在用的时间,依次处理每个陷阱,sum+=di,另用一个堆维护已经处理过的所有陷阱(包括正在处理的)最大的ti,每当sum超过当前di时,取出堆中最大的ti,跳过这个陷阱,sum-=(ti)max,然后--hp。
代码如下
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; #define mxn 25010 int n,k; priority_queue<int> q; struct trap{ int d,t; bool operator < (const trap hehe)const{ return d<hehe.d; } }m[mxn]; int main(){ while(scanf("%d%d",&n,&k)!=EOF){ while(!q.empty()) q.pop(); for(int i=0;i<n;++i) scanf("%d%d",&m[i].t,&m[i].d); sort(m,m+n); int sum=0; int ans=0; for(int i=0;i<n;++i){ sum+=m[i].t; if(ans>=k) break; q.push(m[i].t); while(sum>m[i].d){ sum-=q.top(); q.pop(); ++ans; } } if(ans>=k) ans=-1; printf("%d\n",ans); } return 0; }