[Usaco2012 Feb] Cow Coupons

[Usaco2012 Feb] Cow Coupons

一个比较正确的贪心写法(跑得贼慢。。。)

首先我们二分答案,设当前答案为mid

将序列按照用券之后能省掉的多少排序,那么我们对于两种情况

  1. \(mid \leq k\) 全部取用券后的,取最小的\(mid\)

  2. 排序后我们枚举分界点,对于右边\(p-c\)较大的,我们肯定考虑把k个券用给它们,就可以在左边取\(p\)最小的\(mid-k\)个,和右边的\(c\)最小的\(k\)个即可

    这个我们用堆维护即可

#include<bits/stdc++.h>
using namespace std;
 
#define reg register
typedef long long ll;
#define rep(i,a,b) for(reg int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(reg int i=a,i##end=b;i>=i##end;--i)
 
char IO;
int rd(){
    int s=0,f=0;
    while(!isdigit(IO=getchar())) if(IO=='-') f=1;
    do s=(s<<1)+(s<<3)+(IO^'0');
    while(isdigit(IO=getchar()));
    return f?-s:s;
}
 
template <class T> inline void cmax(T &a,T b){ ((a<b)&&(a=b)); }
template <class T> inline void cmin(T &a,T b){ ((a>b)&&(a=b)); }
 
const int N=5e4+10,P=998244353;
 
int n,k;
ll m;
struct Node{
    int a,b;
    bool operator < (const Node __) const {
        return a-b<__.a-__.b;
    }
} A[N];
 
priority_queue <int> que;
void clear(){
    while(!que.empty()) que.pop();
}
 
ll s1[N],s2[N];
int Check(int mid){
    if(mid<=k) {
        clear();
        rep(i,1,n) que.push(-A[i].b);
        ll res=0;
        rep(i,1,mid) res-=que.top(),que.pop();
        return res<=m;
    } else {
        clear();
        ll t=0;
        rep(i,1,n) {
            que.push(A[i].a);t+=A[i].a;
            while((int)que.size()>mid-k) t-=que.top(),que.pop();
            if((int)que.size()==mid-k) s1[i]=t;
        } // 预处理两边最小的几个
        ll res=1e18;
        rep(i,mid-k,n-k) cmin(res,s1[i]+s2[i+1]); //枚举分界点
        return res<=m;
    }
}
 
int main(){
    n=rd(),k=rd(),scanf("%lld",&m);
    rep(i,1,n) A[i].a=rd(),A[i].b=rd();
    sort(A+1,A+n+1);
    ll t=0;
    drep(i,n,1) {
        que.push(A[i].b);t+=A[i].b;
        while((int)que.size()>k) t-=que.top(),que.pop();
        if((int)que.size()==k) s2[i]=t;
    }
    int l=1,r=n,res=0;
    while(l<=r) {
        int mid=(l+r)>>1;
        if(Check(mid)) l=mid+1,res=mid;
        else r=mid-1;
    }
    printf("%d\n",res);
}
 
 

代码细节可能挂了,如果有hack数据发在评论里谢谢

posted @ 2019-11-08 16:08  chasedeath  阅读(165)  评论(0编辑  收藏  举报