斑羚飞渡 贪心

  

链接:https://ac.nowcoder.com/acm/contest/917/A

首先将羊分为3种

1 自己可以跳过去的   那么ans++

2 不可能跳过去的   那么加入q2 当作被踩的羊

3 只能依靠别人跳过去的   将这些样按照y进行排序  (符合贪心原则  先让弱者跳 这样最后答案才会最多)

然后开始对3进行二分搜索   能跳过去直接+1 

否则加入q1

显然q1的羊  两两之间必然都能跳过去  (反证可以说明)

#include<bits/stdc++.h>
using namespace std;
//input by bxd
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);--i)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m)
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define pb push_back
#define inf 0x3f3f3f3f
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
const int N=1e5;
int n,s,cnt,c,ans,a,b;
struct node
{
    int x,y;
    bool operator<(const node b)const
    {
        if(y!=b.y)
        return y<b.y;
        return x<b.x;
    }
}ss[N];
multiset<node>q1;
multiset<int>q2;

int main()
{
    RII(n,s);
    rep(i,1,n)
    {
        RII(a,b);
        if(a>=s){ ans++;continue; }

        if(a+b<s)
        {
            q2.insert(a);
        }
        else if(a+b>=s)
        {
            ss[++cnt].x=a;
            ss[cnt].y=b;
        }
    }
    sort(ss+1,ss+1+cnt);

    rep(i,1,cnt)
    {
        auto it=q2.lower_bound(s-ss[i].y);

        if(it!=q2.end())
        {
            ans++;
            q2.erase(it);
        }
        else q1.insert(ss[i]);
    }
    cout<<ans+q1.size()/2;

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/bxd123/p/11027138.html