【牛客网】合唱团

链接

在这里插入图片描述
在这里插入图片描述




转换思维很重要。

问出队的最少人数=留下的最多人数

继续分析。怎么求出留下的最多人呢。

假设第i个人一定留下,作为队伍的“中间个头最高的那个人”。我求出i留下作为最高的人时的最多人数。

然后遍历每个人,就知道了可以留下的最多人。

然后我怎么知道,第i人一定在,并作为“中心”的情况下,队列的最多人数呢?

我求出从左到i的最大增序列人数。求出从右到左的最大增序列人数。这样就知道了i留下,作为“中心”时。队列的最大人数。

那我怎么求单方向的,到i为止的增序列最大人数呢。

假设我求从左到右方向。假设我知道了以i左边的每个人为从左到右的增序列的最后一个人的最大人数。以i为最后一个人的增序列中,倒数第二个人可能是左边的所有人(身高小于i),然后我从符合的人中,获取他的最大增序列人数+1,就行了。

那么我需要从左到右维护一个数组。序号i,数值为x:表示:以第i人为队尾,队伍方向从左到右。身高依次递增的最大队伍长度。

同理,我再维护一个从右到左的类似数组。

然后对应位置求和-1,就是以i人为“中间”最高的人时,队伍的总最大人数。

以每个人为“中心”求出一个数组。挑出最大的那个数。此时,离队的人数最少。

import java.util.Scanner;


public class Demo02 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int total = in.nextInt();

            int[] arr = new int[total];
            int[] fromLeft = new int[total];
            int[] fromRight = new int[total];
            for (int i = 0; i < total; i++) {
                fromLeft[i] = 1;
            }
            for (int i = 0; i < total; i++) {
                fromRight[i] = 1;
            }

            for (int i = 0; i < total; i++) {
                arr[i] = in.nextInt();
            }

            // 填充从左到右的递增序列的个数统计
            for (int i = 1; i < total; i++) {
                int max = 1;
                for (int j = 0; j <= i - 1; j++) {
                    if (arr[i] > arr[j]) {
                        max = Math.max(max, fromLeft[j] + 1);
                    }
                }
                fromLeft[i] = max;
            }
            // 填充从右到左的递增序列的个数统计
            for (int i = total - 2; i >= 0; i--) {
                int max = 1;
                for (int j = total - 1; j > i; j--) {
                    if (arr[i] > arr[j]) {
                        max = Math.max(max, fromRight[j] + 1);
                    }
                }
                fromRight[i] = max;
            }

            int max = 0;
            for (int i = 0; i < total; i++) {
                max = Math.max(max, fromLeft[i] + fromRight[i]);
            }
            System.out.println(total-max + 1);
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值