链接:https://ac.nowcoder.com/acm/contest/5670/D
来源:牛客网
题目描述
Inaka composes music. Today's arrangement includes a chord of nnn notes that are pairwise distinct, represented by a permutation p1…np_{1 \dots n}p1…n of integers from 111 to nnn (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:
- Drop-2: Take out the second highest note and move it to the lowest position, i.e. change the permutation to pn−1,p1,p2,…,pn−3,pn−2,pnp_{n-1}, p_1, p_2, \dots, p_{n-3}, p_{n-2}, p_npn−1,p1,p2,…,pn−3,pn−2,pn.
- Invert: Take out the lowest note and move it to the highest position, i.e. change the permutation to p2,p3,…,pn−1,pn,p1p_2, p_3, \dots, p_{n-1}, p_n, p_1p2,p3,…,pn−1,pn,p1.
Any number of consecutive Drop-2 operations is considered a multi-drop. Miyako would like to change the permutation to an ordered permutation, 1,2,…,n1, 2, \dots, n1,2,…,n, in the fewest number of multi-drops possible. Please help her find the number of multi-drops needed.
输入描述:
The first line contains an integer n (2≤n≤5002 \leq n \leq 5002≤n≤500) — the number of notes. The second line contains n space-separated integers p1,p2,…,pnp_1, p_2, \dots, p_np1,p2,…,pn — the original permutation of notes. The input guarantees each integer from 1 to n (inclusive) appears in the permutation exactly once.
输出描述:
Output one integer — the number of multi-drops required to change the permutation to an ordered one.
示例1
输入
复制6 2 4 5 1 3 6
6 2 4 5 1 3 6
输出
复制2
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
8 8 4 7 3 6 2 5 1
输出
复制5
5
转载文章:https://blog.nowcoder.net/n/1e4de66e422a47fdb04c246cdb2e30ed
作者:Dasyatis
个人内容:
题意:给一个长度为n的序列
有两个操作,操作1:把第一个数移到最后,第二个操作,把倒数第二个数移到第一个
操作一一次能做做好多次,能最少要多少套第一个操作。
思路:变链为环(上次第三场的多校B题也有点类似,是把指向起点的指针进行移动来思考)
启发:以后看到对序列进行首尾等相关操作可以往 “变环”和移动起点指针的方向去思考
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=600*2;
typedef long long LL;
int dp[maxn];
int a[maxn];
int b[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
int n;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i],a[i+n]=a[i];
for(int k=1;k<=n;k++)
{
for(int i=k;i<=k+n-1;i++)
{
dp[i]=1;
for(int j=k;j<i;j++)
{
if(a[j]<a[i])
{
dp[i]=max(dp[j]+1,dp[i]);
}
}
}
int res=0;
for(int i=k;i<=k+n-1;i++)
{
res=max(res,dp[i]);
}
b[k]=res;
}
int ans=-1;
for(int i=1;i<=n;i++)
{
ans=max(ans,b[i]);
}
cout<<n-ans<<endl;
return 0;
}
转载内容:
2020 多校第五场 D
https://ac.nowcoder.com/acm/contest/5670/D
做法就是把题目给的序列头尾相接形成一个环状序列,枚举环状序列的起点,答案就是「序列长度减去 LIS(最大上升子序列)」的最小值。
环状序列应该不难想,LIS 是怎么来的跟着样例 1 走一遍就知道了:
1 2 |
|
现在我们在一个盘面上按照顺时针方向摆放序列上的数字,然后模拟一下样例解释的做法,首先他 invert 了很多次,多少次不重要。
Invert, 5 times, changing the permutation to 6,2,4,5,1,3;
我们可以理解为将盘面任意地旋转。
接下来他 Drop-2 了很多次,同样多少次不重要,反正这么多次下来就记一次数。
Drop-2, 3 times, changing the permutation to 4,5,1,6,2,3;
它原话是 Take out the second highest note and move it to the lowest position
,但是这里是一个圆盘,我们可以把盘面当成抽奖转盘,带有一个固定指针的哪种。指针指向的数字往顺时针方向挪一位就是一个 Drop-2 了,如下图所示。挪动的时候,其它数字被挤开相应往顺时针挪动。然后重复操作。
把上面三步 Drop-2 合成一步 multi-drop 来理解,你会发现就是把 1、4、5 这三个数当成一个整体往顺时针挪动一位。
如果你把数字 3 作为参照系,你会发现是 1、4、5 绕开 3 顺时针移动一位。如果你把 1、4、5 这个整体作为参照系,你会发现是数字 3 逆时针移动了三位。因为每次 multi-drop 前后都可以随便旋转转盘,可以再进一步理解,multi-drop 就是将某一个数字移动到任意的位置,就像下面的这样。
那么答案就很显然了,求出 LIS 之后,不在最大上升子序列的数,我们每一个数花一个 multi-drop 操作移动到正确的位置就好了。