個人心得:周測時,這一題我是做了很久的,在一步一步糾正錯誤,本來以為用基本的動態規划,當滿足倆邊比前面大或者小的時候狀態
轉移,后面發現其實這樣的動態轉移不具有無后效性,有時去掉以后還可能影響結果,后面又想到了最長遞增序列,一下子腦洞大開,
對呀,正反同時求以一個數為尾的遞增數列不就得了,然后在遞歸1到n就可以了,acm,真不愧是鍛煉思維的,其實這些算法思想啥的是
一些著名數學家和計算機方面的專家窮極一生或者廢寢忘食得來的,必有它可學的道理,還是挺服氣的,為自己的弱感到悲哀,為自己
小腦袋感到頭大,腦洞小但是頭大,哈哈哈哈....不笑了,看題
描述
N位同學站成一排,音樂老師要請其中的(N-K)位同學出列,使得剩下的K位同學不交換位置就能排成合唱隊形。
合唱隊形是指這樣的一種隊形:設K位同學從左到右依次編號為1, 2, …, K,他們的身高分別為T1, T2, …, TK,則他們的身高滿足T1 < T2 < … < Ti , Ti > Ti+1 > … > TK (1 <= i <= K)。
你的任務是,已知所有N位同學的身高,計算最少需要幾位同學出列,可以使得剩下的同學排成合唱隊形。
輸入
輸入的第一行是一個整數N(2 <= N <= 100),表示同學的總數。第一行有n個整數,用空格分隔,第i個整數Ti(130 <= Ti <= 230)是第i位同學的身高(厘米)。
輸出
輸出包括一行,這一行只包含一個整數,就是最少需要幾位同學出列。樣例輸入
8 186 186 150 200 160 130 197 220
樣例輸出
4
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<string> 6 #include<algorithm> 7 using namespace std; 8 const int inf=999999999; 9 int z[105],ji[105]; 10 int person[105]; 11 int person1[105]; 12 int main(){ 13 int n; 14 cin>>n; 15 int flag=1; 16 for(int i=1;i<=n;i++) 17 cin>>person[i]; 18 for(int i=n;i>=1;i--) 19 person1[flag++]=person[i]; 20 memset(z,0,sizeof(z)); 21 memset(ji,0,sizeof(ji)); 22 for(int i=1;i<=n;i++) 23 { 24 for(int j=1;j<i;j++) 25 { 26 if(person[j]<person[i]&&max(0,z[j])+1>z[i]) 27 z[i]=max(0,z[j])+1; 28 if(person1[j]<person1[i]&&max(0,ji[j])+1>ji[i]) 29 ji[i]=max(0,ji[j])+1; 30 31 } 32 } 33 for(int i=1;i<=n;i++) 34 { 35 z[i]+=1,ji[i]+=1; 36 } 37 int ans=0; 38 for(int i=1;i<=n;i++) 39 ans=max(ans,z[i]+ji[n-i+1]-1); 40 cout<<n-ans<<endl; 41 return 0; 42 }