E. The Contest Educational Codeforces Round 76 (Rated for Div. 2)

时间:2019-11-16 20:48:06   收藏:0   阅读:123

题意: 给出三个序列的值( 1到 n),移动三个序列中的一些值,使得第一个序列是1 ~ n的一个前缀,第三个序列为1~ 2的一个后缀,第二个序列是其他的值。问移动次数的最小值。

分析:

先放个例子。
技术分享图片

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MA=2e5+5;

int a[5],vis[MA],dp[MA][5];

int main()
{
    int n=0;
    scanf("%d%d%d",&a[0],&a[1],&a[2]);
    for(int k=0;k<=2;++k){
        n=a[k];
        int x;
        for(int i=0;i<n;++i){
            scanf("%d",&x);
            vis[x]=k+1;        //构造新序列
        }
    }
    n=a[0]+a[1]+a[2];
    for(int i=1;i<=n;++i){
        if(vis[i]==1){  
            dp[i][1]=dp[i-1][1]; 
            dp[i][2]=min(dp[i-1][2]+1,dp[i-1][1]+1);   
            dp[i][3]=min(dp[i-1][1]+1,min(dp[i-1][2]+1,dp[i-1][3]+1));
        }
        else if(vis[i]==2){
            dp[i][1]=dp[i-1][1]+1;
            dp[i][2]=min(dp[i-1][1],dp[i-1][2]);
            dp[i][3]=min(dp[i-1][1]+1,min(dp[i-1][2]+1,dp[i-1][3]+1));
        }
        else if(vis[i]==3){
            dp[i][1]=dp[i-1][1]+1;
            dp[i][2]=min(dp[i-1][1]+1,dp[i-1][2]+1);
            dp[i][3]=min(dp[i-1][1],min(dp[i-1][2],dp[i-1][3]));
        }
    }
    printf("%d\n",min(dp[n][1],min(dp[n][2],dp[n][3])));
    return 0;
}

原文:https://www.cnblogs.com/A-sc/p/11873098.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!