2020牛客多校第五场D题Drop Voicing(思维 dp lis)

题目链接:https://ac.nowcoder.com/acm/contest/5670/D

题意:输入一个n个数的序列,你有两种操作,第一种把数组第一个移到最后一个,第二种把数组的倒数第二个移到第一个,连续第二种操作为一次花费(一次花费无论多少次),输出最少费用使序列变为升序,即为[1,2,3,4,5.....n]

题解:第一种操作并不能更换数字之间的顺序,无论怎么样置换,都可以把他看做成一个环。第二种操作我们就可以把一个数字移动,结合第一种操作可以移动到他原来的位置。这样我们就求要移动多少个数字就可以了,移动多少个数字变成升序?那不就是lis,枚举n次第一种操作后的数组,每次计算lis,ans=n-lis;

这里第一种操作,我们用STL种的rotate

rotate(beg,newBeg,end)
将区间[beg,end)内的元素进行旋转,执行后*newBeg成为新的第一元素;

#include <bits/stdc++.h>
using namespace std;
const int maxn=500+7;
typedef long long ll;
int a[maxn];
int dp[maxn];
int lis(int n){
    int res = 0;
    for(int i = 0; i < n; i ++){
        dp[i] = 1;
        for(int j = 0; j < i; j ++){
            if(a[j] < a[i]){
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        res = max(res, dp[i]);
    }
    return res;
}
int main(){
    int t,n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
    }
    int ans=0;
    for(int i=0;i<n;i++){
        ans=max(ans,lis(n));
        rotate(a,a+1,a+n);
    }
    printf("%d\n",n-ans);
    return 0;
}

 

posted @ 2020-08-05 13:43  杰瑞与汤姆  阅读(139)  评论(0编辑  收藏  举报