zoukankan      html  css  js  c++  java
  • 华为机试题——合唱队

    题目描述

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

    说明:

    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; } }
     
     
  • 相关阅读:
    设计模式目录
    垃圾收集器
    598. Range Addition II
    Java中的四种引用
    垃圾回收算法
    645. Set Mismatch
    java 8中撤销永久代,引入元空间
    L2-013. 红色警报 (并查集)
    POJ 1127 Jack Straws (线段相交)
    L2-014. 列车调度 (DP)
  • 原文地址:https://www.cnblogs.com/huangyichun/p/6389086.html
Copyright © 2011-2022 走看看