题意:
给 定 一 个 长 度 为 n 的 排 列 ( n 个 整 数 都 介 于 [ 1 , n ] , 且 不 重 复 ) , 允 许 两 种 操 作 : 给定一个长度为n的排列(n个整数都介于[1,n],且不重复),允许两种操作: 给定一个长度为n的排列(n个整数都介于[1,n],且不重复),允许两种操作:
① 、 D r o p − 2 : 将 倒 数 第 二 个 数 放 到 开 头 。 ①、Drop-2:将倒数第二个数放到开头。 ①、Drop−2:将倒数第二个数放到开头。
② 、 I n v e r t : 将 开 头 的 第 一 个 数 放 到 最 后 。 ②、Invert:将开头的第一个数放到最后。 ②、Invert:将开头的第一个数放到最后。
每 次 操 作 允 许 选 择 ① 或 ② 连 续 进 行 多 次 , 每次操作允许选择①或②连续进行多次, 每次操作允许选择①或②连续进行多次,
求 最 少 需 要 进 行 几 次 ① 操 作 ( 每 次 可 以 连 续 多 次 将 倒 数 第 二 个 数 放 到 开 头 ) , 求最少需要进行几次①操作(每次可以连续多次将倒数第二个数放到开头), 求最少需要进行几次①操作(每次可以连续多次将倒数第二个数放到开头),
可 将 排 列 排 好 序 ( 从 1 到 n 递 增 ) 。 可将排列排好序(从1到n递增)。 可将排列排好序(从1到n递增)。
示例1
输入:
6
2 4 5 1 3 6
输出
2
说明
An optimal solution with two multi-drops is:
示例2
输入
8
8 4 7 3 6 2 5 1
输出
5
分析:
观 察 操 作 ① 和 操 作 ② , 我 们 不 妨 将 整 个 排 列 看 作 是 一 个 环 。 观察操作①和操作②,我们不妨将整个排列看作是一个环。 观察操作①和操作②,我们不妨将整个排列看作是一个环。
我 们 分 析 操 作 ① , 即 每 次 可 以 将 连 续 的 某 一 段 数 p k , p k + 1 , . . . , p n − 1 逆 序 后 移 动 到 开 头 , 我们分析操作①,即每次可以将连续的某一段数p_{k},p_{k+1},...,p_{n-1}逆序后移动到开头, 我们分析操作①,即每次可以将连续的某一段数pk,pk+1,...,pn−1逆序后移动到开头,
在 环 上 相 当 于 将 这 一 段 逆 时 针 旋 转 移 动 到 开 头 , 在环上相当于将这一段逆时针旋转移动到开头, 在环上相当于将这一段逆时针旋转移动到开头,
也 就 是 说 , p k , p k + 1 , . . . , p n − 1 相 对 于 p n 逆 时 针 移 动 到 了 p 1 , p 2 , . . . , p k − 1 这 一 段 的 前 面 , 也就是说,p_{k},p_{k+1},...,p_{n-1}相对于p_n逆时针移动到了p_1,p_2,...,p_{k-1}这一段的前面, 也就是说,pk,pk+1,...,pn−1相对于pn逆时针移动到了p1,p2,...,pk−1这一段的前面,
等 价 于 将 p n 移 动 到 了 环 上 的 某 个 位 置 上 。 等价于将p_n移动到了环上的某个位置上。 等价于将pn移动到了环上的某个位置上。
因 此 操 作 ① 可 归 纳 为 : 将 序 列 中 的 任 意 一 个 数 移 动 到 任 意 位 置 上 。 因此操作①可归纳为:将序列中的任意一个数移动到任意位置上。 因此操作①可归纳为:将序列中的任意一个数移动到任意位置上。
分 析 操 作 ② , 我 们 发 现 环 上 任 意 两 数 之 间 的 相 对 位 置 不 改 变 , 因 此 , 操 作 ② 对 排 序 无 作 用 。 分析操作②,我们发现环上任意两数之间的相对位置不改变,因此,操作②对排序无作用。 分析操作②,我们发现环上任意两数之间的相对位置不改变,因此,操作②对排序无作用。
所 以 , 要 求 连 续 进 行 操 作 ① 的 最 少 次 数 , 我 们 需 要 找 到 序 列 上 的 最 长 上 升 子 序 列 , 所以,要求连续进行操作①的最少次数,我们需要找到序列上的最长上升子序列, 所以,要求连续进行操作①的最少次数,我们需要找到序列上的最长上升子序列,
在 最 长 上 升 子 序 列 中 插 入 其 他 的 数 , 最 终 答 案 即 序 列 长 度 n − 环 上 最 长 上 升 子 序 列 的 长 度 。 在最长上升子序列中插入其他的数,最终答案即序列长度n-环上最长上升子序列的长度。 在最长上升子序列中插入其他的数,最终答案即序列长度n−环上最长上升子序列的长度。
具体做法:
从 1 到 n 枚 举 环 的 起 点 i , 对 每 个 起 点 i 求 一 遍 最 长 上 升 子 序 列 的 D P , 保 存 最 大 值 m a x l , 输 出 n − m a x l 。 从1到n枚举环的起点i,对每个起点i求一遍最长上升子序列的DP,保存最大值maxl,输出n-maxl。 从1到n枚举环的起点i,对每个起点i求一遍最长上升子序列的DP,保存最大值maxl,输出n−maxl。
时间复杂度: O ( n 3 ) O(n^3) O(n3)
代码:
#include
#include
#include
#include
#include
using namespace std;
const int N=510;
int n,a[N<<1];
int f[N<<1];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
a[n+i]=a[i];
}
int maxl=0;
for(int i=1;i<=n;i++)
for(int j=i;j<=i+n-1;j++)
{
f[j]=1;
for(int k=i;k<j;k++)
if(a[k]<a[j])
f[j]=max(f[j],f[k]+1);
maxl=max(maxl,f[j]);
}
cout<<n-maxl<<endl;
return 0;
}