题目描述

  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;
}