日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[NOI2019] 序列(模拟费用流)

發布時間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [NOI2019] 序列(模拟费用流) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原先自己想的建圖:

正確建圖:

但是 n 太大了,所以考慮模擬費用流:

注意:
在1中,
若選的兩個位置相同,則為情況2,不用減 f;
若選的位置在另一序列中已被選,則為情況3或4,不用減 f;
若選的位置在另一序列中都已被選,則為情況5,把 f 加1。

在3,4中,
若選的位置在另一序列中都已被選,則為情況5,把 f 加1。

更多細節詳見代碼:

#include<iostream> #include<cstdio> #include<queue> using namespace std; typedef long long ll; const int N=200010; struct que{int val,id;que(){}que(int v,int i){val=v;id=i;} }; bool operator < (const que a, const que b){return a.val<b.val; } priority_queue<que> pa,pb,pc,pd,psum,nul; int T,n,K,L,A[N],B[N],flagA[N],flagB[N]; int main(){scanf("%d",&T);while(T--){pa=pb=pc=pd=psum=nul;//初始化 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++){pa.push(que(A[i],i));pb.push(que(B[i],i));psum.push(que(A[i]+B[i],i));flagA[i]=flagB[i]=0;}int f=K-L;ll ans=0;for(int i=1;i<=K;i++){que ra,rb,rc,rd,rsum;while(!pa.empty()){ra=pa.top();if(!flagA[ra.id]) break;pa.pop();} while(!pb.empty()){rb=pb.top();if(!flagB[rb.id]) break;pb.pop();}if(f>0){if(flagB[ra.id]) f+=1;if(flagA[rb.id]) f+=1;if(ra.id==rb.id) f+=1;flagA[ra.id]=flagB[rb.id]=1;pa.pop();pb.pop(); pc.push(que(A[rb.id],rb.id));pd.push(que(B[ra.id],ra.id));f-=1;ans+=ra.val+rb.val;continue;}while(!pc.empty()){rc=pc.top();if(!flagA[rc.id]) break;pc.pop();} while(!pd.empty()){rd=pd.top();if(!flagB[rd.id]) break;pd.pop();}while(!psum.empty()){rsum=psum.top();if(!flagA[rsum.id]&&!flagB[rsum.id]) break;psum.pop();} int maxn=-1;int x=-1;if(!psum.empty()&&rsum.val>maxn) maxn=rsum.val,x=2;if(!pc.empty()&&!pb.empty()&&rc.val+rb.val>maxn) maxn=rc.val+rb.val,x=3;if(!pd.empty()&&!pa.empty()&&rd.val+ra.val>maxn) maxn=rd.val+ra.val,x=4;ans+=maxn;if(x==2){flagA[rsum.id]=flagB[rsum.id]=1;psum.pop();}else if(x==3){if(flagA[rb.id]) f+=1;flagA[rc.id]=flagB[rb.id]=1;pc.pop();pb.pop();pc.push(que(A[rb.id],rb.id));}else if(x==4){if(flagB[ra.id]) f+=1;flagA[ra.id]=flagB[rd.id]=1;pa.pop();pd.pop();pd.push(que(B[ra.id],ra.id));}}printf("%lld\n", ans);}return 0; }

總結

以上是生活随笔為你收集整理的[NOI2019] 序列(模拟费用流)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。