题目描述
计算最少出列多少位同学,使得剩下的同学排成合唱队形
设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。
所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
注意不许改变队列元素的先后顺序
请注意处理多组输入输出!
最长子序列问题
先找到每一个位置i左侧的最长上升子序列长度numL[i]:每一个位置左侧最长子序列长度等于其左侧比它小的所有位置的最长子序列长度中的最大值+1
再找到每一个位置i右侧的最长下降子序列长度numR[i]:每一个位置右侧最长子序列长度等于其右侧比它小的所有位置的最长子序列长度中的最大值+1
然后求出所有位置的最长序列长度=左侧最长子序列长度+右侧最长子序列长度-1(因为该位置被算了两次,所以减1)
然后用数目减去最长序列长度就是答案(牛客大神原话)
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String in = "";
while ((in = br.readLine()) != null && !"".equals(in)) {
int perCount = Integer.parseInt(in);
in = br.readLine();
String[] temp = in.split(" ");
// 转成int
int[] intArr = new int[temp.length];
for(int i = 0; i < temp.length; i++) {
intArr[i] = Integer.parseInt(temp[i]);
}
System.out.println(calc(intArr));
}
}
public static int calc(int[] arr) {
int[] numL = new int[arr.length];
int[] numR = new int[arr.length];
for(int i = 0; i < numL.length; i++) {
for(int j = 0; j < i; j++) {
if (arr[j] < arr[i]) {
numL[i] = Math.max(numL[j], numL[i]);
}
}
numL[i] += 1;
}
// printArr(numL);
for(int i = arr.length - 1; i >= 0; i--) {
for(int j = arr.length - 1; j > i; j--) {
if (arr[i] > arr[j]) {
numR[i] = Math.max(numR[j], numR[i]);
}
}
numR[i] += 1;
}
// printArr(numR);
int max = 0;
for(int i = 0; i < arr.length; i++) {
max = Math.max(max, numL[i] + numR[i] - 1);
}
return arr.length - max;
}
public static void printArr(int[] a) {
for(int i = 0; i< a.length; i++) {
System.out.print(" " + a[i]);
}
System.out.println();
}
}