• 华为机试题——合唱队


    题目描述

    计算最少出列多少位同学,使得剩下的同学排成合唱队形

    说明:

    N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。 
    合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,   则他们的身高满足存在i(1<=i<=K)使得T1<T2<......<Ti-1<Ti>Ti+1>......>TK。 
    你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。

    输入描述:

    整数N

    输出描述:

    最少需要几位同学出列

    输入例子:
    8
    186 186 150 200 160 130 197 200
    输出例子:
    4

    思路:

      求两次最长递增子序列,先从左往右求递增子序列a[n],采用动态规划的方法,具体见代码。再求从右到左的递增子序列b[n]。

      

      假设输入为:

           186 186 150 200 160 130 197 200
        a[n] 1 1 1 2 2 1 3 4 从左到右
        b[n] 3 3 2 3 2 1 1 1 从右到左
        c[n] 4 4 3 5 4 2 4 5
      取c[i]最大值 5, i = 3; 所以包括3这个位置左边有2个是合唱队列的,包括3这个位置右边有3个是合唱队列的。
      由于3被计算了2次,所以合唱队列为:2+3-1 = 4人。
      由于总人数为:8 , 所以需要抽出8-4人。

        
    import java.util.*;
    public class Main{
        
        public static void main(String[] args){
            Scanner scanner = new Scanner(System.in);
            while(scanner.hasNext()){
                int num = scanner.nextInt();
                int[] arr = new int[num];
                for(int i=0; i<num; i++){
                    arr[i] = scanner.nextInt();
                }
                
                int[] a = getBestQueue(arr, true);
                int[] b = getBestQueue(arr,false);
                
                int len = 0;
                
                //获取最长合唱形
                for(int i=0; i<num; i++){
                    int n = a[i] + b[i];
                    if(n > len){
                        len = n;
                    }
                }
                
                System.out.println(num-len+1);
                
            }
        }
        
      
       //求递增子序列
    public static int[] getBestQueue(int[] array, boolean acceding){ int length = array.length; int a[] = new int[length]; if(acceding){ //从左到右的递增子序列 for(int i=0; i<length; i++){ a[i] = 1; for(int j=0; j<i; j++){ if(array[i] > array[j]){ a[i] = Math.max(a[i], a[j]+1); } } } }else{ //从右到左的递增子序列 for(int i=length-1; i >=0 ; i--){ a[i] = 1; for(int j=length-1; j>i; j--){ if(array[i] > array[j]){ a[i] = Math.max(a[i], a[j]+1); } } } } return a; } }
     
     
  • 相关阅读:
    关于2019-nCoV事件中新媒体的作用
    评估移民宇宙计划
    关于2019-nCoV事件,分析自己的焦虑心理
    肺炎阴云仍未散去,今天捡到一个贝壳
    关于新型肺炎,重点是毒性
    提高效率的方法
    《白说》读书笔记
    MIPS下载运行busybox
    camera模组笔记
    求知领域
  • 原文地址:https://www.cnblogs.com/huangyichun/p/6389086.html
Copyright © 2020-2023  润新知