华为OJ——合唱队问题
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,
他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)
使得Ti<T2<......<Ti-1<Ti>Ti+1>......>TK。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,
可以使得剩下的同学排成合唱队形。
输入
整数N
一行整数,空格隔开,N位同学身高
输出
最少需要几位同学出列
样例输入 8 186 186 150 200 160 130 197 200
样例输出 4
思路:
求出到到某个位置的最大递增序列(从头到此处),及最大递减序列(从此处到尾部)
然后两者相加的最大值减1,就是所留人数最多的情况。
求最大递增递减序列的见前边
*/
public static int[] LasLength(int[] n)//从前往后动态规划求最大递增序列
{
int l=n.length;
int[] r=new int[l];
r[0]=1;
for(int i=1;i<l;i++){
r[i]=1;
for(int j=0;j<i;j++){
if(n[j]<n[i]&&r[j]>r[i]-1)r[i]=r[j]+1;
}
}
return r;
}
public static int[] LdsLength(int[] n)//从后往前动态规划求最长递减序列
{
int l=n.length;
int[] r=new int[l];
r[l-1]=1;
for(int i=l-1;i>=0;i--){
r[i]=1;
for(int j=l-1;j>i;j--){
if(n[j]<n[i]&&r[j]>r[i]-1)r[i]=r[j]+1;
}
}
return r;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
//n为人数
int n=sc.nextInt();
int[] height=new int[n];
for (int i = 0; i < n; i++)
{
height[i]=sc.nextInt();
}
sc.close();
if(n==0) System.out.println(0);
else
{
int[] r1=LasLength(height);
int[] r2=LdsLength(height);
int Max=r1[0]+r2[0]-1;
for(int i=1;i<n;i++)//求出可以留的人数的最大值Max
{
if(r1[i]+r2[i]-1>Max)Max=r1[i]+r2[i]-1;
}
System.out.print(n-Max);
}
}
}