合唱隊形(解題思維的鍛煉)


個人心得:周測時,這一題我是做了很久的,在一步一步糾正錯誤,本來以為用基本的動態規划,當滿足倆邊比前面大或者小的時候狀態

轉移,后面發現其實這樣的動態轉移不具有無后效性,有時去掉以后還可能影響結果,后面又想到了最長遞增序列,一下子腦洞大開,

對呀,正反同時求以一個數為尾的遞增數列不就得了,然后在遞歸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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM