传送门

 

题意:

  给出一个序列,你可以将任意一个数移到最前面;

  求最少需要移动多少次,可以是此序列变成非递减序列;

思路:

  定义 (ai,aj) 为逆序对 ( i < j , ai > aj ), 求出 aj 的最大值,用变量 curMax 存储;

  遍历一遍数组,求解 ans;

  对于∀ i ∈[1,n] 

  ①如果 ai < curMax , ans++;

  ②如果 ai == curMax , 那么需要特殊判断:

    (2.1)如果 ai 之前不曾出现比 curMax 大的数,不需要移动;

    (2.2)反之,ans++;

AC代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+50;
 4 
 5 int n;
 6 int a[maxn];
 7 int preMax[maxn];///preMax[i]:[1,i]的最大值
 8 
 9 int Solve()
10 {
11     int curMax=0;
12     for(int i=n;i >= 1;--i)
13         if(a[i] < preMax[i-1])///找逆序对(x,y)的最大的y
14             curMax=max(curMax,a[i]);
15     int ans=0;
16     bool flag=false;
17     for(int i=1;i <= n;++i)
18     {
19         if(a[i] > curMax)///判断[1,i]有无比curMax大的数出现
20             flag=true;
21         if(a[i] < curMax)///情况①
22             ans++;
23         if(flag && a[i] == curMax)///情况2.2
24             ans++;
25     }
26     return ans;
27 }
28 int main()
29 {
30     int test;
31     while(~scanf("%d",&test))
32     {
33         while(test--)
34         {
35             scanf("%d",&n);
36             preMax[0]=0;
37             for(int i=1;i <= n;++i)
38             {
39                 scanf("%d",a+i);
40                 preMax[i]=max(preMax[i-1],a[i]);
41             }
42             printf("%d\n",Solve());
43         }
44     }
45     return 0;
46 }
View Code

相关文章: