問題描述:java
N 位同窗站成一排,音樂老師要請其中的(N-K)位同窗出列,而不改變其餘同窗的位置,使得剩下的K位同窗排成合唱隊形。合唱隊形要求:設K位同窗從左到右 依次編號爲1,2…,K,他們的身高分別爲T1,T2,…,TK,則他們的身高知足 T1<T2...<Ti>Ti+1>…>TK(1<=i<=K)。已知全部N位同窗的身高,計算最少須要幾位 同窗出列,可使得剩下的同窗排成最長的合唱隊形。 app
問題分析:spa
假設第i位同窗爲個子最高的同窗,咱們先對其左邊的同窗求最大上升子序列,再對其右邊的同窗求最大降低子序列,而後二者相加再減1(第i位同窗被重複計算 了一次),便獲得第i位同窗爲最高個時所能排成的最長合唱隊形。若是咱們對這N位同窗都執行此操做,即可獲得每位同窗爲最高個時所能排成的最長合唱隊形, 選取其中最長的合唱隊形做爲最終的結果。 .net
從 上述的分析能夠看出,咱們能夠將問題分紅互相不獨立的子問題,只要獲得子問題的最優解,即可獲得整個問題的最優解。咱們能夠用一張表來記錄全部已解決問題 的答案,從而避免了重複計算。這裏的一個關鍵問題即是:如何獲得第i位同窗的最大上升子序列和最大降低子序列。假如這N位同窗的身高分別 爲:176,163,150,180,170,130,167,160,咱們用up[i]來記錄第i位同窗的最大上升子序列。若是要獲得180同窗爲最高 個時的最大上升子序列即up[4],咱們只需求出前3位同窗所能造成的最大上升子序列,將其加1便可;要獲得前3位同窗所造成的最大上升子序列,便要求得 前2位同窗的最大上升子序列,再加上1便可;一樣要獲得前2位同窗的最大上升子序列,便要求得第1位同窗的最大上升子序列。所以這是一個遞推關係,只要我 們將前i個同窗爲最高個時作造成的最大上升子序列的值記錄下來,取其中最大值加1即可獲得第i位同窗的最大上升子序列即up[i]。同理咱們用 down[i]來記錄第i位同窗的最大降低子序列,只要咱們將後(N-i)位同窗每位同窗爲最高個時的最大降低子序列記錄下來,取其中最大者再加1即可得 到第i位同窗爲最高個時的最大降低子序列即down[i]。那麼,第i位同窗爲最高個時作能造成的最長合唱隊形的長度爲up[i]+down[i]-1。 求得全部同窗爲最高個時所能造成的最長合唱隊形的長度,取其中最大值爲最終的結果。blog
[java] view plain copy索引