CF377B Preparing for the Contest(贪心+优先队列)

显然具有单调性,我们二分答案,看看能否完成要求

完成要求的条件是在指定天数中可以完成做题并且价格不超过s。天数越多显然价格会降低

之后我们把问题排序,并且把能力也排序,倒着做

因为我们一旦选取了一个人,就希望这个人能干最多的事情,所以我们用优先队列维护能干这件事的价值最小的人

只有倒着做才是正确的。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll,ll> pll;
const int N=2e5+10;
const int M=2e6+10;
const int inf=0x3f3f3f3f;
const ll mod=998244353;
int n,m,S;
pll a[N];
int ans[N];
struct node{
    ll a,b,id;
    bool operator <(const node &t) const{
        return b>t.b;
    }
}g[N];
bool cmp(node a,node b){
    return a.a<b.a;
}
bool check(int x){
    ll sum=0;
    priority_queue<node> q;
    int i;
    int cnt=n;
    for(i=m;i>=1;i--){
        while(cnt&&g[cnt].a>=a[i].first){
            q.push(g[cnt--]);
        }
        if(q.empty())
            return false;
        int j;
        for(j=i;j>max(i-x,0);j--){
            ans[a[j].second]=q.top().id;
        }
        i-=x;
        i++;
        sum+=q.top().b;
        q.pop();
    }
    return sum<=S;
}
int main(){
    ios::sync_with_stdio(false);
    cin>>n>>m>>S;
    int i;
    for(i=1;i<=m;i++){
        cin>>a[i].first;
        a[i].second=i;
    }
    for(i=1;i<=n;i++){
        cin>>g[i].a;
        g[i].id=i;
    }
    for(i=1;i<=n;i++)
        cin>>g[i].b;
    sort(a+1,a+1+m);
    sort(g+1,g+1+n,cmp);
    int l=0,r=m+1;
    while(l<r){
        int mid=l+r>>1;
        if(check(mid))
            r=mid;
        else
            l=mid+1;
    }
    if(l==m+1){
        cout<<"NO"<<endl;
    }
    else{
        cout<<"YES"<<endl;
        check(l);
        for(i=1;i<=m;i++)
            cout<<ans[i]<<" ";
        cout<<endl;
    }
    return 0;
}
View Code

 

posted @ 2020-09-05 10:57  朝暮不思  阅读(252)  评论(0编辑  收藏  举报