显然具有单调性,我们二分答案,看看能否完成要求
完成要求的条件是在指定天数中可以完成做题并且价格不超过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; }