题目描述
Inaka composes music. Today's arrangement includes a chord of notes that are pairwise distinct, represented by a permutation
of integers from
to
(inclusive) denoting the notes from the lowest to the highest.
Her friend, Miyako, sneaks in and plays a trick by altering the chord with the following two operations. : Take out the second highest note and move it to the lowest position, i.e. change the permutation to
. Invert: Take out the lowest note and move it to the highest position, i.e. change the permutation to
.
Any number of consecutive operations is considered a multi-drop. Miyako would like to change the permutation to an ordered permutation,
, in the fewest number of
possible. Please help her find the number of
needed.
输入描述
The first line contains an integer
— the number of notes.
The second line contains n space-separated integers — the original permutation of notes.
The input guarantees each integer from to
(inclusive) appears in the permutation exactly once.
输出描述
Output one integer — the number of required to change the permutation to an ordered one.
示例1
输入
6 2 4 5 1 3 6
输出
2
说明
An optimal solution with two multi-drops is:
Invert, times, changing the permutation to
;
,
times, changing the permutation to
;
,
times, changing the permutation to
;
,
time, changing the permutation to
.
示例2
输入
8 8 4 7 3 6 2 5 1
输出
5
分析
对于操作 ,可以将
看作一个环,环的长度为
,即进行
次操作
,排列还原;对于操作
,可以将
看作一个环,环的长度为
,即进行
次操作
,排列还原。形成的两个环如图所示,
代表当前排列
的第一个数,
代表位于大环(长度为
的环)上,而在小环(长度为
的环)外的数。

小环和大环可以独立顺时针转动,两个指针 和
的位置是固定不动的;当转动小环,视为进行了一次
,当转动大环,视为进行多次
。可以发现,当转动小环,可以将位于小环外的数字,插入任意两个数字之间。在图中,当前
位于
和
之间,转动一次小环,
就在
和
之间了;显然,进行一次
,可以将
放入任何你想要的位置。更一般的,若要该边数字
在大环中的相对其他数字位置,应该首先用多次
将
放入
标记的位置,然后进行一次
。我们要对大环上的数字进行排序,那么只需要通过若干次操作,利用小环调整一些数字的相对位置,令大环上形成
这样的环,再进行几次
即可将原序列
完成排序。
那么问题就变得简单:每次调整一个数的位置就要进行一次 ,因此要调整尽可能少的数字。不妨找出大环上的一个
(最长上升子序列),其长度为
;对于在
上的
个数字不作调整,只需要调整
个数字的相对位置;显然,这样的方案使得需要调整的数字个数最小。对于不在
上的
个数字,用
次
和若干次
,即可将这
个数字一一放入正确的位置,完成排序。
计算环上的 长度时,可以枚举环的起点,对
个起点各求一次
,取长度最大的即可。时间复杂度为
。
代码
/******************************************************************
Copyright: 11D_Beyonder All Rights Reserved
Author: 11D_Beyonder
Problem ID: 2020牛客暑期多校训练营(第五场) Problem D
Date: 8/20/2020
Description: Circle, LIS
*******************************************************************/
#include<algorithm>
#include<iostream>
#include<cstdio>
using namespace std;
const int N=504;
int n;
int p[N];
int a[N];
int dp[N];
int main(){
cin>>n;
int i,j;
for(i=1;i<=n;i++){
scanf("%d",p+i);
}
int ans=0x3f3f3f3f;
//枚举环的起点
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
//环确定了起点为i
//于是可以环拉成链
a[j]=p[i+j-1-n*(i+j-1>n)];
}
//求LIS
int len=1;
dp[1]=a[1];
for(j=2;j<=n;j++){
if(a[j]>dp[len]){
dp[++len]=a[j];
}else{
*lower_bound(dp+1,dp+1+len,a[j])=a[j];
}
}
ans=min(n-len,ans);//最小调整次数
}
cout<<ans<<endl;
return 0;
} 
京公网安备 11010502036488号