AcWing:482. 合唱队形
题型: LeetCode 第40场双周赛D 5559. 得到山形数组的最少删除次数
最长上升子序列扩展
思路:
- 正着求一次最长上升子序列, 反着求一次
- 然后将 f 数组 and g 数组的最长上升子序列长度相加,得到最长的山形数组的长度 ans
- 总长度 - ans = 需要踢出队列的人数
AC Code
import java.util.*;
import static java.lang.System.out;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int len = in.nextInt();
int[] f = new int[len], g = new int[len];
// 初始化
Arrays.fill(f, 1);
Arrays.fill(g, 1);
int[] arr = new int[len];
for(int i = 0; i < len; i++) arr[i] = in.nextInt();
// 朴素 dp
// 正
for(int i = 0; i < len; i++) {
for(int j = 0; j < i; j++) {
if(arr[i] > arr[j]) f[i] = Math.max(f[i], f[j] + 1);
}
}
// 反
for(int i = len - 1; i >= 0; i--) {
for(int j = len - 1; j > i; j--) {
if(arr[i] > arr[j]) g[i] = Math.max(g[i], g[j] + 1);
}
}
// 计算结果
int ans = 0;
// 最长的 山形数组
for(int i = 0; i < len; i++) ans = Math.max(ans, f[i] + g[i] - 1);
// 请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形
// 就是最少需要几位同学出列
out.println(len - ans);
}
}