侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 674 篇文章
  • 累计创建 128 个标签
  • 累计收到 20 条评论

目 录CONTENT

文章目录

【动态规划】合唱队形「动态规划之LIS模型」

GabrielxD
2023-02-10 / 0 评论 / 0 点赞 / 115 阅读 / 626 字
温馨提示:
本文最后更新于 2023-02-14,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

482. 合唱队形 - AcWing题库


NN 位同学站成一排,音乐老师要请其中的 (NK)(N-K) 位同学出列,使得剩下的 KK 位同学排成合唱队形。

合唱队形是指这样的一种队形:设 KK 位同学从左到右依次编号为 12K1,2…,K ,他们的身高分别为 T1T2TKT_1,T_2,…,T_K ,  则他们的身高满足 T1<<Ti>Ti+1>>TK(1iK)T_1 < … < T_i > T_{i+1} > … > T_K(1 \le i \le K)

你的任务是,已知所有 NN 位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

输入格式

输入的第一行是一个整数 NN ,表示同学的总数。

第二行有 NN 个整数,用空格分隔,第 ii 个整数 TiT_i 是第 ii 位同学的身高(厘米)。

输出格式

输出包括一行,这一行只包含一个整数,就是最少需要几位同学出列。

数据范围

2N1002 \le N \le 100 ,
130Ti230130 \le T_i \le 230

输入样例:

8
186 186 150 200 160 130 197 220

输出样例:

4

解题

方法一:动态规划

思路

【动态规划】登山 基本一样,只不过这题求的是序列长度减去最长先上升后下降最长子序列长度。

模板:【动态规划】最长上升子序列

代码

import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        in.nextToken();
        int n = (int) in.nval;
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            in.nextToken();
            a[i] = (int) in.nval;
        }
        int[] f = new int[n], g = new int[n];
        for (int i = 0; i < n; ++i) {
            f[i] = 1;
            for (int j = 0; j < n; ++j) {
                if (a[j] < a[i]) f[i] = Math.max(f[i], f[j] + 1);
            }
        }
        int mx = 1;
        for (int i = n - 1; i >= 0; --i) {
            g[i] = 1;
            for (int j = n - 1; j > i; --j) {
                if (a[j] < a[i]) g[i] = Math.max(g[i], g[j] + 1);
            }
            mx = Math.max(mx, f[i] + g[i] - 1);
        }
        System.out.println(n - mx);
    }
}
0

评论区