• [PA2014]Bohater


    BZOJ

    题意:在一款电脑游戏中,你需要打败(n(n<=100000))只怪物(从1到n编号).为了打败第i只怪物,你需要消耗(a[i])点生命值,但怪物死后会掉落血药,使你恢复(b[i])点生命值。任何时候你的生命值都不能降到0(或0以下).请问是否存在一种打怪顺序,使得你可以打完这n只怪物而不死掉.

    分析:很明显的贪心策略,首先打能够回血的怪物,再打剩下的怪物.而能够回血的怪物中,按照消耗的生命值从小到大排序(保证先打能打的).剩下的怪物按照回血量从大到小排序(反正都是掉血,保证每次回血尽量多一点)

    排序后模拟做就好了.然后记得开(long) (long).

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=100005;
    struct ppx{int x,y,id;}c[N],d[N];
    inline bool cmp1(ppx x,ppx y){return x.x<y.x;}
    inline bool cmp2(ppx x,ppx y){return x.y>y.y;}
    int main(){
    	int n=read();ll m=read(),tot=0,sum=0;
    	for(int i=1;i<=n;++i){
    		int a=read(),b=read();
    		if(a<=b){
    			c[++tot].x=a;
    			c[tot].y=b;
    			c[tot].id=i;//便于输出方案
    		}//能够回血的放一起
    		else{
    			d[++sum].x=a;
    			d[sum].y=b;
    			d[sum].id=i;
    		}//剩下的放一起
    	}
    	sort(c+1,c+tot+1,cmp1);
    	sort(d+1,d+sum+1,cmp2);//分别排序
    	for(int i=1;i<=tot;++i){//模拟
    		m-=c[i].x;
    		if(m<=0){puts("NIE");return 0;}
    		m+=c[i].y;
    	}
    	for(int i=1;i<=sum;++i){//模拟
    		m-=d[i].x;
    		if(m<=0){puts("NIE");return 0;}
    		m+=d[i].y;
    	}
    	puts("TAK");
    	for(int i=1;i<=tot;++i)printf("%d ",c[i].id);
    	for(int i=1;i<=sum;++i)printf("%d ",d[i].id);
        return 0;
    }
    
    
  • 相关阅读:
    登录Mysql看不到Mysql库
    七牛云使用记录
    FFmpeg工具
    解决VMware下CentOS连不上网络问题
    14.中介者模式
    二十三种设计模式(三)
    23种设计模式(二)
    搭建ssm环境
    文件的字符流与字节流读写
    设计模式之用工厂模式实现计算器
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11542870.html
Copyright © 2020-2023  润新知