LIS(思维题) - Drop Voicing - 2020牛客暑期多校训练营(第五场)

LIS(思维题) - Drop Voicing - 2020牛客暑期多校训练营(第五场)

题意:

给 定 一 个 长 度 为 n 的 排 列 ( n 个 整 数 都 介 于 [ 1 , n ] , 且 不 重 复 ) , 允 许 两 种 操 作 : 给定一个长度为n的排列(n个整数都介于[1,n],且不重复),允许两种操作: n(n[1,n])

① 、 D r o p − 2 : 将 倒 数 第 二 个 数 放 到 开 头 。 ①、Drop-2:将倒数第二个数放到开头。 Drop2

② 、 I n v e r t : 将 开 头 的 第 一 个 数 放 到 最 后 。 ②、Invert:将开头的第一个数放到最后。 Invert

每 次 操 作 允 许 选 择 ① 或 ② 连 续 进 行 多 次 , 每次操作允许选择①或②连续进行多次,

求 最 少 需 要 进 行 几 次 ① 操 作 ( 每 次 可 以 连 续 多 次 将 倒 数 第 二 个 数 放 到 开 头 ) , 求最少需要进行几次①操作(每次可以连续多次将倒数第二个数放到开头), ()

可 将 排 列 排 好 序 ( 从 1 到 n 递 增 ) 。 可将排列排好序(从1到n递增)。 (1n)

示例1
输入:

6
2 4 5 1 3 6

输出

2

说明

An optimal solution with two multi-drops is:

  • Invert, 5 times, changing the permutation to 6,2,4,5,1,3;
  • Drop-2, 3 times, changing the permutation to 4,5,1,6,2,3;
  • Invert, 4 times, changing the permutation to 2,3,4,5,1,6;
  • Drop-2, 1 time, changing the permutation to 1,2,3,4,5,6.

示例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,...,pn1

在 环 上 相 当 于 将 这 一 段 逆 时 针 旋 转 移 动 到 开 头 , 在环上相当于将这一段逆时针旋转移动到开头,

也 就 是 说 , 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,...,pn1pnp1,p2,...,pk1

等 价 于 将 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。 1niiDPmaxlnmaxl

时间复杂度: 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;
}

你可能感兴趣的:(DP,动态规划,算法,ACM,LIS,最长上升子序列)