描述

给出一个\(1\)\(n\)的排列,每次可以移动一个数到一个任意位置。问要达到状态\(1,2,3……n\)至少移动多少次\((1\le N\le 10^6)\)

题解

比较简单的一题,题目意思是让我们把一个数列变得有序,并且可以移动任意数,问最少次数。

可能我们没法直接求要移动多少次,但我们可以求出有多少个数不要移动(最长上升子序列),然后把其他数按照插入排序一样排好(注意任意数都可以移动到任意位置),这样一定是最优解。

注意一下这题的数据,\(O(n^2)\)的暴力肯定过不了,要用\(O(n\log n)\),具体求法可以看一下导弹拦截

代码

#include<bits/stdc++.h>
using namespace std;
int a[10000001];
int main()
{
int test=1;
while(test--)
{
int n;
scanf("%d",&n);
int m,tot=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&m);
if(m>a[tot])
a[++tot]=m;
else
{
int k=upper_bound(a+1,a+tot+1,m)-a;
a[k]=m;
}
}
printf("%d\n",n-tot);
}
return 0;
}