若d[x]<a[x],杀这个怪是有收益的,可以按d值从小到大杀。
若d[x]>a[x],考虑反过来的过程,如果都杀完后血量是S,那么从后向前就是 S-a[i]+d[i],相当于第一种情况,需要按a值从大到小杀。
分两部分排序模拟即可。
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
int n;
struct aa
{
ll a,b,id;
}t1[500009],t2[500009];
bool cmp1(aa a,aa b)
{
return a.b<b.b;
}
bool cmp2(aa a,aa b)
{
return a.a>b.a;
}
int n1,n2;
ll z;
int main()
{
scanf("%d%lld",&n,&z);
ll x,y;
for (int i=1;i<=n;i++)
{
scanf("%lld%lld",&x,&y);
if (x<y) t1[++n1].b=x,t1[n1].a=y,t1[n1].id=i;
else t2[++n2].b=x,t2[n2].a=y,t2[n2].id=i;
}
sort(t1+1,t1+n1+1,cmp1);
sort(t2+1,t2+n2+1,cmp2);
ll nowa=z;
for (int i=1;i<=n1;i++)
{
if (nowa<=t1[i].b)
{
printf("NIE");
return 0;
}
nowa+=-t1[i].b+t1[i].a;
}
for (int i=1;i<=n2;i++)
{
if (nowa<=t2[i].b)
{
printf("NIE");
return 0;
}
nowa+=-t2[i].b+t2[i].a;
}
printf("TAK\n");
for (int i=1;i<=n1;i++) printf("%d ",t1[i].id);
for (int i=1;i<=n2;i++) printf("%d ",t2[i].id);
return 0;
}
总结
1:对于排序贪心的题,这道题是属于分情况贪心的