题意:n个怪,杀每个怪会掉x点血,杀死怪后有个血瓶可以恢复y点血,给定初始血量,问是否可以杀死所有的怪。
思路:这题的思路真是巧妙……首先分成两部分,一部分是杀掉怪可以回血的,另一部分是杀掉怪要掉血的,那么对于可以回血的,显然,先杀那些伤害低的,因为你的血量是一直增加的,所以伤害高的留在后面就好了。至于会掉血的,不妨反过来看,把伤害看做血瓶,把血瓶看做伤害,从最终的状态往回倒流,那么你就会发现,这和第一种是同一个情况了。。。这思路真是厉害,想了半天奇怪的贪心没贪过去Orz
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#include<bitset>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-6
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
struct Node
{
int x,y,id;
Node(int x = 0,int y = 0,int id = 0):x(x),y(y),id(id){}
}na[maxn],nb[maxn];
int ans[maxn];
bool vis[maxn];
bool cmp1(Node a,Node b)
{
return a.x < b.x;
}
bool cmp2(Node a,Node b)
{
return a.y > b.y;
}
int main()
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n;
ll hp;
while(~scanf("%d%lld",&n,&hp))
{
int m1 = 0,m2 = 0;
int x,y;
for(int i = 1;i <= n;++i)
{
scanf("%d%d",&x,&y);
if(x <= y)
na[m1++] = Node(x,y,i);
else
nb[m2++] = Node(x,y,i);
}
sort(na,na + m1,cmp1);
sort(nb,nb + m2,cmp2);
memset(vis,0,sizeof(vis));
int tot = 0;
for(int i = 0;i < m1;++i)
{
if(hp > na[i].x)
{
hp += na[i].y - na[i].x;
ans[tot++] = na[i].id;
}
else
break;
}
for(int i = 0;i < m2;++i)
{
if(hp > nb[i].x)
{
hp += nb[i].y - nb[i].x;
ans[tot++] = nb[i].id;
}
else
break;
}
if(tot != n)
printf("NIE\n");
else
{
puts("TAK");
for(int i = 0;i < tot;++i)
{
if(i) printf(" ");
printf("%d",ans[i]);
}
puts("");
}
}
return 0;
}