首页 > 其他 > 详细

逆向思维——cf1241D

时间:2019-10-17 16:54:50      阅读:46      评论:0      收藏:0      [点我收藏+]
/*
给定一个序列a,每次可以把值为x的所有元素放到a的首部或尾部,问将a变为lis的最少操作步数
对原序列离散化后重新打标记,
可以反着来考虑这个问题:即固定连续的元素值为[l,r]的点不动,那么剩下的所有元素值至多多进行一次操作,就可以让这个序列变成lis
所以求出这个最长合法的连续元素值段落即可 
*/
#include<bits/stdc++.h>
using namespace std;
#define N 300005
int n,a[N],b[N],L[N],R[N];

int main(){
    int t;cin>>t;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];

        sort(b+1,b+1+n);
        int tot=unique(b+1,b+1+n)-b-1;
        
        
        for(int i=1;i<=tot;i++)
            L[i]=0x3f3f3f3f,R[i]=0; 
    
    
        for(int i=1;i<=n;i++){
            a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
            L[a[i]]=min(L[a[i]],i);
            R[a[i]]=max(R[a[i]],i);
        }
        
        
        int ans=0,last=0,len=0;
        for(int i=1;i<=tot;i++){
            if(L[i]>last){
                last=R[i];
                len++;
                ans=max(ans,len);
            }
            else {
                last=R[i];
                len=1;
                ans=max(ans,len);
            }
        }
        cout<<tot-ans<<\n;
    }
} 

 

逆向思维——cf1241D

原文:https://www.cnblogs.com/zsben991126/p/11692941.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!