[CF1257E] The Contest

有三个序列 (a.b.c),每次操作可以把一个序列中的一个数移动到另一个序列中,问最少操作几次后,可以使得 (a) 序列里的所有数小于 (b) 里面的所有数,(b) 里面的小于 (c) 里面的。

Solution

从结果倒过来考虑,假设三个序列各自有序,那么可以保持不动的部分就是三个序列连在一起的最长上升子序列

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 1000005;

int x,y,z,n,p[N],q[N],r[N],a[N],f[N],ans;

void sh(int &x,int y) {
    x=min(x,y);
}

signed main() {
    ios::sync_with_stdio(false);
    cin>>x>>y>>z;
    n=x+y+z;
    for(int i=1;i<=x;i++) cin>>p[i];
    for(int i=1;i<=y;i++) cin>>q[i];
    for(int i=1;i<=z;i++) cin>>r[i];
    sort(p+1,p+x+1);
    sort(q+1,q+y+1);
    sort(r+1,r+z+1);
    for(int i=1;i<=x;i++) a[i]=p[i];
    for(int i=1;i<=y;i++) a[i+x]=q[i];
    for(int i=1;i<=z;i++) a[i+x+y]=r[i];
    memset(f,0x3f,sizeof f);
    for(int i=1;i<=n;i++) sh(f[lower_bound(f+1,f+n+1,a[i])-f],a[i]);
    for(int i=1;i<=n;i++) if(f[i]<1e9) ans=i;
    cout<<n-ans;
}

原文地址:https://www.cnblogs.com/mollnn/p/12595682.html