[TJOI2013]拯救小矮人 nlogn贪心

时间:2019-08-30
本文章向大家介绍[TJOI2013]拯救小矮人 nlogn贪心,主要包括[TJOI2013]拯救小矮人 nlogn贪心使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

[TJOI2013]拯救小矮人 nlogn贪心

考试的时候忘记了DP,乱搞了一个贪心。DP是枚举每一个人选或不选,而贪心是先排序,然后能走就走,不能走就找一个(已经走了的或当前这个)最大的垫在下面。详细见代码。求一组hack数据,已经和正解大数据小数据拍了过百万组,和机房大佬手动思考hack无果。如果大家有想法可以下方讨论提出,谢谢。


#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define rg register int

using namespace std;

int n,m,ans;
int s[200005];
bool f[200005];
priority_queue<int > q;

struct su{
    int x,y,v,id;
    inline bool operator <(const su &i)const{
        if(v==i.v)return y<i.y;
        return v<i.v;
    }
}a[200005];

inline int qr(){
    register char ch; register bool sign=0; rg res=0;
    while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
    while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
    if(sign)return -res; else return res;
}

int main(){
    freopen("in.in","r",stdin);
    freopen("cpp.out","w",stdout);
    n=qr();
    for(rg i=1;i<=n;++i)
        a[i].x=qr(),a[i].y=qr();
    m=qr();
    for(rg i=1;i<=n;++i){
        a[i].id=i;
        a[i].v=a[i].x+a[i].y; //排序关键字
    } sort(a+1,a+n+1);
    for(rg i=n;i>=1;--i)s[i]=s[i+1]+a[i].x; //求后缀和
    rg res=0; ll v=0;
    for(rg i=1;i<=n;++i){
        if(s[i]+a[i].y+v>=m)q.push(a[i].x),++res; //能走就走,并将身高加入队列中记录最大值
        else{
            ans=max(res,ans); //不能走就找一个最大的身高,垫在下面(如下文的if)
            if(!q.empty()&&a[i].x<q.top()&&q.top()+s[i]+a[i].y+v>=m)v+=q.top(),q.pop(),q.push(a[i].x);
            else v+=a[i].x;
        }ans=max(res,ans);
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/812-xiao-wen/p/11437209.html