九度1500-出操隊形

題目描述:
在讀高中的時候,天天早上學校都要組織全校的師生進行跑步來鍛鍊身體,每當出操令吹響時,你們就開始往樓下跑了,而後身高矮的排在隊伍的前面,身高較高的就要排在隊尾。忽然,有一天出操負責人想了一個主意,想要變換一下隊形,就是當你們都從樓上跑下來後,全部的學生都隨機地佔在一排,而後出操負責人從隊伍中抽取出一部分學生,使得隊伍中剩餘的學生的身高從前日後看,是一個先升高後降低的「山峯」形狀。聽說這樣的形狀可以給你們帶來好運,祝願你們在學習的道路上勇攀高峯。(注,山峯只有一邊也符合條件,如1,一、2,二、1均符合條件)
輸入:
輸入可能包含多個測試樣例。
對於每一個測試案例,輸入的第一行是一個整數n(1<=n<=1000000):表明將要輸入的學生個數。
輸入的第二行包括n個整數:表明學生的身高(cm)(身高爲不高於200的正整數)。
輸出:
對應每一個測試案例,輸出須要抽出的最少學生人數。
樣例輸入:
6
100 154 167 159 132 105
5
152 152 152 152 152
樣例輸出:
0
4
分析:
這裏應使用O(nlogn)的算法。先求整體遞增子序列的長度,再求遞減子序列的長度。這裏爲了複用LIS(最長上升序列長度)函數,把原來的數組逆序一下,就至關於求遞減子序列的長度了。
參考代碼以下:
 
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<stdlib.h>
 4 
 5 using namespace std;
 6 
 7 int LongestGrowingNumberLength( int* arr,int length,int start)//從start處開始遞增數組的最大長度
 8 {
 9     if(arr==NULL||length<=0||start<0) return 0;
10     int* begin=arr+start;
11     int* next=begin+1;
12     int count=1;
13     while(next<arr+length)
14     {
15         if(*begin==*next)
16         {
17          next++;
18          begin++;
19         }
20         if(*begin<*next)
21         {
22             *begin=*next;
23             next++;
24             count++;
25         }
26         else next++;
27     }
28     return count;
29 }
30 
31 int GrowingNumberLengthCore(int* arr,int length,int start,int end)//最大正序遞增加度
32 {
33     if(arr==NULL||length<0||start<0||end>length-1) return -1;
34     int MaxValue=LongestGrowingNumberLength(arr,length,0);
35     for(int i=1;i<end;i++)
36     {   
37        int L=LongestGrowingNumberLength(arr,length,i);
38         if(MaxValue< L)
39         {MaxValue=L;}
40     }
41     return MaxValue;
42 }
43 
44 void main()
45 {
46     int n;
47     cin>>n;
48     int* array=new int[n+1];
49     int* resever=new int[n+1];
50     for(int i=0;i<n;i++)
51     {cin>>array[i];}
52     for(i=0;i<n;i++)
53     {resever[i]=array[n-1-i];}
54     int grow=GrowingNumberLengthCore(array,n,0,n-1);//最大正序遞增加度
55     int down=GrowingNumberLengthCore(resever,n,0,n-1);//最大正序遞減長度也就是最大逆序遞增加度
56     cout<<grow<<endl;
57     cout<<down<<endl;
58     cout<<(n+1-grow-down)<<endl;//最少刪除的元素數
59 }
相關文章
相關標籤/搜索