• bzoj 3709: [PA2014]Bohater 贪心


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

    我们对所有怪物分类讨论,将所有 $a[i]geqslant d[i]$ 的怪我放入 $A$,所有 $a[i]<d[i]$ 的放入 $B$.

    显然,对于所有 $B$ 中的怪物,肯定是越打生命值越低的,所以要优先打能让生命值升高的 $A$.

    而 $A$ 中一定是按照 $d[i]$ 递增的顺序去打,因为反正所有怪物都能使血量增加,那肯定要从耗费小的开始打.

    如果发现 $A$ 中有怪物打不了,那么问题就一定无解了.

    打完 $A$ 中所有怪物,再考虑打 $B$ 中的怪物.

    我们发现一个东西:我们只是安排了不同的顺序,但是减掉的 $d[i]$ 总量和加回的 $a[i]$ 总量却是恒定的,所以最终血量是确定的.

    假设最终血量为 $C$,那么倒数第二次的血量是 $C-a[i]+d[i]$,而这种情况下 $a[i]<d[i]$ ,所以我们又将问题转化为了第一种情况:在减掉的不超过 $C$ 的情况下打尽量多的怪:从后向前回溯优先打 $a[i]$ 小的,那么从前向后就是优先杀 $a[i]$ 大的.

    排序然后输出方案即可.      

    #include <bits/stdc++.h> 
    #define N 100005 
    #define LL long long 
    using namespace std; 
    void setIO(string s) 
    {
        string in=s+".in"; 
        freopen(in.c_str(),"r",stdin);       
    }
    struct data 
    {      
        LL a,d; 
        int id; 
        data(LL a=0,LL d=0,int id=0):a(a),d(d),id(id){}   
    }a[N],b[N];    
    bool cmp1(data a,data b) 
    {
        return a.a<b.a; 
    }      
    bool cmp2(data a,data b) 
    {
        return a.d>b.d;                                      
    }
    int main() 
    { 
        // setIO("input");  
        int n,i,j,t1=0,t2=0;  
        LL z; 
        scanf("%d%lld",&n,&z);      
        for(i=1;i<=n;++i)       
        {
            LL x,y; 
            scanf("%lld%lld",&x,&y);      
            if(y>=x) a[++t1]=data(x,y,i);   
            else b[++t2]=data(x,y,i);   
        }
        sort(a+1,a+1+t1,cmp1); 
        sort(b+1,b+1+t2,cmp2);  
        for(i=1;i<=t1;++i) 
        {
            if(z<=a[i].a) 
            { 
                printf("NIE
    "); 
                return 0; 
            }
            else 
            {
                z+=a[i].d-a[i].a; 
            }
        }
        for(i=1;i<=t2;++i) 
        {
            if(z<=b[i].a) 
            {
                printf("NIE
    "); 
                return 0; 
            }
            else 
            {
                z+=b[i].d-b[i].a;   
            }
        }
        printf("TAK
    ");   
        for(i=1;i<=t1;++i) printf("%d ",a[i].id);  
        for(i=1;i<=t2;++i) printf("%d ",b[i].id);   
        return 0; 
    }
    

      

  • 相关阅读:
    JavaScript 简介
    数据库的链接语句
    sqlserver 大杂烩
    数据库操作
    Filter Big Picture
    struts2配置有命名空间的Action: 解决No configuration found for the specified action错误
    Firefox的Firebug调试
    jQuery判断元素显示或隐藏, is 函数
    Jsp Tag
    java revisit
  • 原文地址:https://www.cnblogs.com/guangheli/p/11768737.html
Copyright © 2020-2023  润新知