动态规划
思路见代码注释
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(System.out);
int n = Integer.parseInt(br.readLine());
String[] split = br.readLine().split(" ");
int[] nums = Arrays.stream(split).mapToInt(Integer::parseInt).toArray();
int[] left = new int[n], right = new int[n];
// 先找到每个位置 i 左侧的最长上升子序列
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
left[i] = Math.max(left[i], left[j] + 1);
}
}
}
// 再找到每个位置 i 右边的最长下降子序列
for (int i = n - 1; i >= 0; i--) {
for (int j = n - 1; j > i; j--) {
if (nums[j] < nums[i]) {
right[i] = Math.max(right[i], right[j] + 1);
}
}
}
// 如果以位置 i 为中心,可以构成的合唱队的最大长度为:
// 左侧最长上升子序列长度 + 右侧最长下降子序列长度 + 1
// 加 1 是因为位置 i 没有被计算
int maxLen = 0;
for (int i = 0; i < n; i++) {
maxLen = Math.max(maxLen, left[i] + right[i] + 1);
}
// 所以最少需要出列的人数为:总人数 - 合唱队的最大长度
pw.println(n - maxLen);
pw.flush();
pw.close();
br.close();
}
}

京公网安备 11010502036488号