Educational Codeforces Round 76 (Rated for Div. 2)E(最长上升子序列)

#define HAVE_STRUCT_TIMESPEC
#include<bits/stdc++.h>
using namespace std;
int a[200007],b[200007],c[200007];
int cnt1[200007],cnt2[200007],cnt3[200007];
int mn[200007];
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int k1,k2,k3;
cin>>k1>>k2>>k3;
for(int i=1;i<=k1;++i){
cin>>a[i];
++cnt1[a[i]];
}
for(int i=1;i<=k2;++i){
cin>>b[i];
++cnt2[b[i]];
}
for(int i=1;i<=k3;++i){
cin>>c[i];
++cnt3[c[i]];
}
int n=k1+k2+k3;
for(int i=1;i<=n;++i){
cnt1[i]=cnt1[i-1]+cnt1[i];//小于等于i的个数
cnt2[i]=cnt2[i-1]+cnt2[i];
cnt3[i]=cnt3[i-1]+cnt3[i];
}
for(int i=0;i<=n;++i)
mn[i]=cnt3[i]-cnt2[i];
for(int i=n-1;i>=0;--i)
mn[i]=min(mn[i+1],mn[i]);
int ans=1e9;
for(int i=0;i<=n;++i)
ans=min(ans,cnt2[i]-cnt1[i]+mn[i]+cnt1[n]+cnt2[n]);
/*
假设最终状态为第一个人有0~i,第二个人有i+1~j,第三个人有j+1~n
那么最小操作数等于第二个人和第三个人拥有的1~i个数加上第一个人和第三个人拥有的i+1~j个数加上第一个人和第二个人拥有的j+1~n个数
即cnt2[i]+cnt3[i]+cnt1[j]-cnt1[i]+cnt3[j]-cnt3[i]+cnt1[n]-cnt1[j]+cnt2[n]-cnt2[j]
化简为cnt2[i]-cnt1[i]+cnt3[j]-cnt2[j]+cnt1[n]+cnt2[n]
从0到n枚举i,只剩下cnt3[j]-cnt2[j]一个变量
维护一个后缀数组mn[i]表示[i,n]中最小的cnt3[j]-cnt2[j]
*/
cout<<ans;
return 0;
}

猜你喜欢

转载自www.cnblogs.com/ldudxy/p/11876625.html