题意:
给出一个序列,你可以将任意一个数移到最前面;
求最少需要移动多少次,可以是此序列变成非递减序列;
思路:
定义 (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 }