2019浙江省程序设计竞赛 E:Sequence in the Pocket(思维)

版权声明:本文为博主原创文章,顺手点个赞叭~有问题欢迎指出(*╹▽╹*) https://blog.csdn.net/qq_41117236/article/details/89608276

目录

 

【题面】

【题解】

【代码】


【题面】

传送门:Sequence in the Pocket

【题解】

题意:给定一个长度为n的序列,可执行一种操作:选定一个元素弹出并压入序列头部。问至少执行多少次操作使得序列最终成为一个非递减序列。

思路:容易得到,要使得操作次数最小,要弹出压入前端的元素要尽可能少,而弹出的所有元素必定存在一种弹出顺序使得它们成为一个非递减序列,所以我们只需要考虑哪些是必须要弹出的元素计数即可。

那么哪些是必须弹出的元素呢?比如序列 1 3 2 7 2 6 ,首先 2 6 是必须弹出的,因为 2 6 比7小,而弹出的元素中最大的元素6比1 3 2 都要大 ,所以1 3 2都要被弹出,所以答案是5.

我们发现,要成为一个非递减的序列又要保证操作尽可能少时,我们只会把比较小的元素弹出放在前面,尽可能保留大的元素,而保留的元素相对位置不变又要保证非递减只有一种情况,所以我们按排完序后的次序从大往小从原序列中从后往前找可以被保留的元素,则其他的元素则是必须被弹出的。

不知道有没有讲清楚qaq

【代码】

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e5+5;
int main()
{
    int t; scanf("%d",&t);
    int a[maxn],b[maxn];
    while(t--){
        int n; scanf("%d",&n);
        for(int i=0;i<n;i++) scanf("%d",&a[i]),b[i]=a[i];
        sort(b,b+n);
        int sum=0,pos=n-1;
        for(int i=n-1;i>=0;i--){
            if(a[i]==b[pos]) pos--;
            else sum++;
        }
        printf("%d\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41117236/article/details/89608276