• [思维] Codeforces Round #591 D. Sequence Sorting


    题意:给定一序列,每次可以选择一个数,并将序列内所有数放在序列最前面/最后面,问使序列有序的最小操作数

     考虑最差情况肯定是不同数字个数 - 1(完全无序和区间交叉)

    考虑交换次数不容易思考,可以反向考虑最多的不用交换就有序的数字,

    思考发现,当两个数字x < y,数字区间无交叉且数值间没有第三个数字时,这两个数字不用动就有序,

    那么将题目数字抽象为线段并离散,使得最大连续数值不交(小数区间在前 大数区间在后)

    总减x即可

    /*
        Zeolim - An AC a day keeps the bug away
    */
     
    //#pragma GCC optimize(2)
    //#pragma GCC ("-W1,--stack=128000000")
    #include <bits/stdc++.h>
    using namespace std;
    #define mp(x, y) make_pair(x, y)
    #define fr(x, y, z) for(int x = y; x < z; ++x)
    #define pb(x) push_back(x)
    #define mem(x, y) memset(x, y, sizeof(x))
    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    typedef std::pair <int, int> pii;
    typedef std::vector <int> vi;
    //typedef __int128 ill;
    const ld PI = acos(-1.0);
    const ld E = exp(1.0);
    const ll INF = 0x3f3f3f3f3f3f3f3f;
    const ll MOD = 386910137;
    const ull P = 13331; 
    const int MAXN = 1e6 + 100;
    
    int arr[MAXN] = {0};
    
    struct lsh
    {
    	int v[MAXN], vl; 
    	lsh() { vl = 0; }
    	void pb(int val) { v[vl++] = val; } //????? 
    	void init() { sort(v, v + vl); vl = unique(v, v + vl) - v; } //?????,???? 
    	int find(int val) { return lower_bound(v, v + vl, val) - v;} //??????
    	int get(int pos) { return v[pos]; }  //???????? 
    };
    
    int mx[MAXN][2];
    int dp[MAXN] = {0};
    
    int main()
    {  
        ios::sync_with_stdio(0);
        cin.tie(0); cout.tie(0);
        //freopen("d:out.txt","w",stdout);
        //freopen("d:in.txt","r",stdin);
       	
       	int n;
       	
       	cin >> n;
    
    	while(n--)
    	{
    		int len;
    		
    		cin >> len;
    		
    		lsh V;
    		
    		for(int i = 0; i < len; ++i)
    		{
    			cin >> arr[i];
    			V.pb(arr[i]);
    			dp[i] = 1;
    		}
    			
    		V.init();
    		
    		for(int i = 0; i < V.vl; ++i)
    		{
    			mx[i][0] = 0x3f3f3f3f;
    			mx[i][1] = 0;
    		}
    		
    		len = unique(arr, arr + len) - arr;
    		
    		for(int i = 0; i < len; ++i)
    		{
    			arr[i] = V.find(arr[i]);
    			mx[arr[i]][0] = min(mx[arr[i]][0], i); //变为线段
    			mx[arr[i]][1] = max(mx[arr[i]][1], i);
    		}
    		
    //		for(int i = 0; i < len; ++i)
    //		{
    //			cout << mx[arr[i]][0] << ' ' << mx[arr[i]][0] << '
    ';
    //		}
    		
    	//	cout << '
    ';
    		
    		int cut = 1;
    		
    		for(int i = 0; i < len; ++i)
    		{
    			if(arr[i] == 0) continue; 
    			if(mx[arr[i] - 1][1] < mx[arr[i]][0]) //计算最大连续递增不交线段数
    			{
    				dp[arr[i]] = dp[arr[i] - 1] + 1;
    				cut = max(cut, dp[arr[i]]);
    			}
    		}
    		
    		cout << V.vl - cut << '
    ';
    		
    	}
       	
    	return 0;
    }
    
    /*
    2
    00001000
    0001000
    000000000000000000000000000100000
    000000000000000000000000000000000100000000000000000000000000000000000001001000000000000000000000000
    00000000000000000000000000000000010000000000000000000000000000000000000100100
    */
  • 相关阅读:
    Array.sort()对象数组排序
    ES6极简数组去重 & 深拷贝
    中文字符按拼音首字母排序(转)
    浏览器常用插件 & 开发常用类库
    异步&分段处理海量数据
    线上环境window.open()新窗口被拦截(转)
    git 版本回退(转)
    CSS字体渐变 & 隐藏浏览器滚动条 & grid布局(转载)
    Python3安装使用SaltStack以及salt-api详解
    Python3之 contextlib
  • 原文地址:https://www.cnblogs.com/zeolim/p/12270316.html
Copyright © 2020-2023  润新知