zoukankan      html  css  js  c++  java
  • codeforces E. The Contest(最长上升子序列)

    题目链接:https://codeforces.com/contest/1257/problem/E

    题意:给三个序列k1,k2,k3,每个序列有一堆数,k1是前缀,k3是后缀,k2是中间,现可以从任意序列中选择一个数加入到另外的序列中,问最小操作次数还原成1-n的原序列(序列内部操作是任意的,不计入操作次数)

    题解:k1,k2,k3分别排一下序,然后k1,k2,k3拼成一个序列,求这个序列的最长上升子序列的长度,然后n - lis就是答案.

    举个例子k1 : 1 2 6

                  k2:   3 4 8

                  k3 :  5 7 9

                 拼接后 1 2 6 3 4 8 5 7 9,最长上升子序列是 1 2 3 4 5 7 9,这些数字是固定不动的,然后让其他的数字6 8插入应有的位置,所以最长操作次数就是2.

    AC代码:

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<set>
    #include<map>
    #include<vector>
    using namespace std;
    typedef long long ll;
    ll mod = 1e9+7;
    int k1,k2,k3,dif;
    const int maxn = 2e5+2 ;
    int a4[maxn];
    void solve(){
    	int n = k1+k2+k3;
        int dp[maxn];
    	int len = 1;
    	dp[1] = a4[0];
    	for(int i = 1;i<n;i++){
    		dp[len+1] = n + 1;
    		int l = 0,r = len + 1,ans = 0;
    		while(l<=r){
    			int mid = (l + r)/2;
    			if(a4[i]<dp[mid]){
    				ans = mid;
    				r = mid - 1;
    			}
    			else{
    				l = mid + 1;
    			}
    		}
    		dp[ans] = a4[i];
    		if(ans>len) len++;
    	}
    	dif = len;
    }
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>k1>>k2>>k3;
    	for(int i = 0;i<k1+k2+k3;i++){
    		cin>>a4[i];
    	}
    	sort(a4,a4+k1);
    	sort(a4+k1,a4+k1+k2);
    	sort(a4+k1+k2,a4+k1+k2+k3);
    	solve(); 
    	cout<<k1+k2+k3 - dif;
    	return 0;
    }
  • 相关阅读:
    Java遍历Map、List、Array
    自签名SSL生成
    oracle_round
    Timestamp_时间戳
    oracle_substr
    eval
    orcale_聚合函数
    oracle_decode
    js_JSON
    sql拼接
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12129622.html
Copyright © 2011-2022 走看看