题解 | #合唱队#

合唱队

https://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;
import java.util.stream.Collectors;

/**
 * 8
 * 186 186 150 200 160 130 197 200
 * 4
 * 说明:
 * 由于不允许改变队列元素的先后顺序,所以最终剩下的队列应该为186 200 160 130或150 200 160 130
 */
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNextLine()) {
            String nextLine = in.nextLine();
            if (Objects.isNull(nextLine) || nextLine.equals("")) {
                break;
            }
            int n = Integer.parseInt(nextLine);
            String line = in.nextLine();
            List<Integer> student = Arrays.stream(line.split(" "))
                                    .map(Integer::parseInt)
                                    .collect(Collectors.toList());
            // dp表示当前状态队伍中,当前人为最高点时,队伍的最多递增人数
            // 左边人数
            int[] dpLeft = new int[student.size()];
            // 右边的人数
            int[] dpRight = new int[student.size()];
            // 初始化
            // 当队伍里面只有1个人时,最终队伍人数就是1
            dpLeft[0] = 1;
            dpRight[student.size() - 1] = 1;
            // 初始最终只有1个人
            int result = 1;
            // 左队伍人数逐渐增加,刷新状态
            for (int i = 0; i < student.size(); i++) {
                // 先默认自成一派
                dpLeft[i] = 1;
                // 当前人的高度
                Integer current = student.get(i);
                // 如果当前的人比前一个遍历还高或者跟它一样高
                // 如果当前的人比前一个遍历还矮,则它的dpLeft值应当是dpLeft中比前一个状态稍微矮一个级的+1
                for (int j = 0; j < i; j++) {
                    if (student.get(j) < current) {
                        dpLeft[i] = Math.max(dpLeft[i], dpLeft[j] + 1);
                    }
                }

            }

            // 右队伍人数逐渐增加,刷新状态
            for (int i = student.size() - 1; i >= 0; i--) {
                // 先默认自成一派
                dpRight[i] = 1;
                // 当前人的高度
                Integer current = student.get(i);
                // 如果当前的人比前一个遍历还高或者跟它一样高
                // 如果当前的人比前一个遍历还矮,则它的dpLeft值应当是dpLeft中比前一个状态稍微高一个级的+1
                for (int j = student.size() - 1; j > i; j--) {
                    if (student.get(j) < current) {
                        dpRight[i] = Math.max(dpRight[i], dpRight[j] + 1);
                    }
                }
            }
            // 左队伍+右队伍,遍历出最大值
            for (int i = 0; i < student.size() - 1; i++) {
                result = Math.max(dpLeft[i] + dpRight[i], result);
            }
            // 需要减去中间那个重复的人,合唱队队伍人数最多
            System.out.println(student.size() - result+1);
        }
    }
}

全部评论

相关推荐

08-23 21:29
已编辑
吉林师范大学 硬件开发
牛马人的牛马人生:前期急啥 前期神仙打架高端局ssp的高级大offer 都是佬们的战争
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务