You are given a sequence 𝑎1,𝑎2,…,𝑎𝑛, consisting of integers.
You can apply the following operation to this sequence: choose some integer 𝑥 and move all elements equal to 𝑥 either to the beginning, or to the end of 𝑎. Note that you have to move all these elements in one direction in one operation.
For example, if 𝑎=[2,1,3,1,1,3,2], you can get the following sequences in one operation (for convenience, denote elements equal to 𝑥 as 𝑥-elements):
[1,1,1,2,3,3,2] if you move all 1-elements to the beginning;
[2,3,3,2,1,1,1] if you move all 1-elements to the end;
[2,2,1,3,1,1,3] if you move all 2-elements to the beginning;
[1,3,1,1,3,2,2] if you move all 2-elements to the end;
[3,3,2,1,1,1,2] if you move all 3-elements to the beginning;
[2,1,1,1,2,3,3] if you move all 3-elements to the end;
You have to determine the minimum number of such operations so that the sequence 𝑎 becomes sorted in non-descending order. Non-descending order means that for all 𝑖 from 2 to 𝑛, the condition 𝑎𝑖−1≤𝑎𝑖 is satisfied.
Note that you have to answer 𝑞 independent queries.
链接🔗
「CodeForces 1241D」Sequence Sorting
题解
我们把每个数字分成最左点和最右点,那么该数字边成为了一个区间「L,R」
连续上升区间就是连续并且相邻两个数字的区间没有相交
我们的目标则是将整个区间数组变成连续上升的
答案为N - 未移动前的最长连续上升区间长度
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <map>
#include <iostream>
#define all(x) x.begin(),x.end()
#define pb push_back
using namespace std;
const int maxd = 2e5+10;
typedef long long ll;
int main()
{
// freopen("a.in","r",stdin);
// freopen("k.out","w",stdout);
int t;scanf("%d",&t);
while(t--)
{
int n;scanf("%d",&n);
vector<int> a(n),b(n);
map<int,int> mp;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
b[i] = a[i];
}
sort(all(b));
b.erase(unique(all(b)),b.end());
int m =b.size();
vector<int> l(m),r(m),dp(m);
for(int i=0;i<m;i++) mp[b[i]] = i;
for(int i=0;i<n;i++) r[mp[a[i]]] = i;
for(int i=n-1;i>=0;i--) l[mp[a[i]]] = i;
//for(int i=0;i<m;i++) printf("%d %d\n",l[i],r[i]);
for(int i=0;i<m;i++) dp[i] = 1;
int ans = 1;
for(int i=1;i<m;i++)
{
if(r[i-1] < l[i]) dp[i] = dp[i-1] +1;
ans = max(dp[i],ans);
}
printf("%d\n",m-ans);
}
return 0;
}