The 16th Zhejiang Provincial Collegiate Programming Contest Sponsored E.Sequence in the Pocket(思维题)

传送门

题意:

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

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

思路:

  定义 (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

求逆序对(x,y)中最大的y 需要树状数组求么????

答案是否定的,直接遍历一遍,记录一下前i个数得最大值就好了;

but,比赛的时候,用的是树状数组求最大的y;

按理说,树状数组求逆序对是树状数组最基本的操作(quq,逃);

代码写搓可还行(debug俩小时,然鹅,还没该对,以至于我都开始怀疑数据了);

经过这次debug,这辈子都不会写搓树状数组求逆序对得代码了;

学弟思路(tql):

  遍历一遍数组 a ,判断最多有多少个连续得最大值,假设有 x 个,输出 n-x;

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 b[maxn];
 8 
 9 int Solve()
10 {
11     memcpy(b+1,a+1,sizeof(int)*n);
12     sort(b+1,b+n+1);
13     int ans=n;
14     for(int i=n;i >= 1;--i)
15         if(b[ans] == a[i])///判断最多的连续的最大值
16             ans--;
17     return ans;
18 }
19 int main()
20 {
21     int test;
22     while(~scanf("%d",&test))
23     {
24         while(test--)
25         {
26             scanf("%d",&n);
27             for(int i=1;i <= n;++i)
28                 scanf("%d",a+i);
29             printf("%d\n",Solve());
30         }
31     }
32     return 0;
33 }
View Code

猜你喜欢

转载自www.cnblogs.com/violet-acmer/p/10788237.html