题目传送门
。
解法:
怪物有加血有扣血的。
分情况讨论:
首先先将加血的先打完。
那么加血的按照怪物消耗的血量从小到大排序。
反正都是加血。肯定先打消耗血量小的啊。
打完之后打扣血的怪物。
要知道最后一个怪物打完其实不需要吃它的草药了。
也就是说最后一个怪物的草药应该希望尽量小。
样例就是一个很好的说明。
所以扣血的怪物按照草药补的多少从大到小排序。
中间判断一下即可。
代码实现:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
struct node {int d,a,id;}a[110000],b[110000];
bool cmp(node n1,node n2) {return n1.d<n2.d;}
bool cmp1(node n1,node n2) {return n1.a>n2.a;}
int main() {
int n;ll z;scanf("%d%lld",&n,&z);int len=0,sum=0;
for(int i=1;i<=n;i++) {
int x,y;scanf("%d%d",&x,&y);
if(y>=x) {a[++len].d=x;a[len].a=y;a[len].id=i;}
else {b[++sum].d=x;b[sum].a=y;b[sum].id=i;}
}
sort(a+1,a+1+len,cmp);
for(int i=1;i<=len;i++) {
if(z<=a[i].d) {printf("NIE\n");return 0;}
z=z-a[i].d+a[i].a;
}
sort(b+1,b+1+sum,cmp1);
for(int i=1;i<=sum;i++) {
if(z<=b[i].d) {printf("NIE\n");return 0;}
z=z-b[i].d+b[i].a;
}
printf("TAK\n");
for(int i=1;i<=len;i++)printf("%d ",a[i].id);
for(int i=1;i<=sum;i++)printf("%d ",b[i].id);
printf("\n");
return 0;
}