问题描述: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索引