神奇贪心
考虑进行K次操作,每次选择一个a中的点和b中的点。
首先,任何时刻,如果a与b中未成对的点对数量小于K-L,我们都可以选择a中最大的点和b中最大的点。
否则,我们选择一下三种策略中收益最高的那个(如果相同则随便选)
1.找到一个i,满足ai与bi均未被选择,选择ai与bi
2.找到一个i,满足ai未被选择,bi已经被选择,选择ai与任意一个b
3.找到一个i,满足bi未被选择,ai已经被选择,选择bi与任意一个a
正确性懒得写了,大概就是如果未成对的点没选满,你早晚都要选,还不如就现在选了。
否则的话你一定得从这三个方案中选一个,用反证法证明这么选一定不会更差就行了。
#include<bits/stdc++.h> #define file(s) freopen(s".in","r",stdin);freopen(s".out","w",stdout); #define P 998244353 #define mid (l+r>>1) #define N 1100000 #define lb(x) (x&(-x)) #define inf 999999999 #define M 1658561 #define ll long long #define cl(x) while(!x.empty()) x.pop(); #define mem(x) memset(x,0,sizeof(x)); using namespace std; int n,m,mx,x,y,d1,d2,d3,v1,v2,v3,a[N],b[N],va[N],vb[N],use,T,K,L; ll res; struct cp1{ bool operator() (int x,int y){return a[x]<a[y];}}; struct cp2{ bool operator() (int x,int y){return b[x]<b[y];}}; struct cp3{ bool operator() (int x,int y){return a[x]+b[x]<a[y]+b[y];}}; priority_queue<int ,vector<int>,cp1>q1,q4; priority_queue<int ,vector<int>,cp2>q2,q5; priority_queue<int ,vector<int>,cp3>q3; int main(){ //file("s"); scanf("%d",&T); while(T--){ res=use=0; cl(q1);cl(q2);cl(q3);cl(q4);cl(q5); scanf("%d%d%d",&n,&K,&L); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++) q1.push(i),q2.push(i); for(int i=1;i<=K-L;i++){ x=q1.top(),y=q2.top(); res+=a[x]+b[y],va[x]=1,vb[y]=1,q1.pop(),q2.pop(); } for(int i=1;i<=n;i++){ if(va[i]&&vb[i])use++; else if(va[i])q5.push(i); else if(vb[i])q4.push(i); else q3.push(i); } while(L--){ while(!q1.empty()&&va[q1.top()])q1.pop(); while(!q2.empty()&&vb[q2.top()])q2.pop(); while(!q3.empty()&&(va[q3.top()]||vb[q3.top()])) q3.pop(); while(!q4.empty()&&(va[q4.top()])) q4.pop(); while(!q5.empty()&&(vb[q5.top()])) q5.pop(); x=q1.top(),y=q2.top(); if(use){ res+=a[x]+b[y];va[x]=vb[y]=1; if(!vb[x]) q5.push(x); if(!va[y]) q4.push(y); use+=vb[x]+va[y]-(x==y)-1; }else{ d1=q4.empty()?0:q4.top(),d2=q5.empty()?0:q5.top(),d3=q3.empty()?0:q3.top(); v1=a[d1]+b[y],v2=b[d2]+a[x],v3=a[d3]+b[d3],mx=max(v1,max(v2,v3)); if(v1==mx) res+=a[d1]+b[y],va[d1]=vb[y]=1,va[y]? use++,void():q4.push(y); else if(v2==mx) res+=b[d2]+a[x],vb[d2]=va[x]=1,vb[x]? use++,void():q5.push(x); else if(v3==mx) res+=a[d3]+b[d3],va[d3]=vb[d3]=1; } } printf("%lld ",res); for(int i=1;i<=n;i++) va[i]=vb[i]=0; } return 0; }