华为在线编程系列-合唱队(动态规划的应用)

  • 题目:

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

    • 输入输出

      输入描述
      8(总共有N为同学)
      186 186 150 200 160 130 197 200
      输出描述
      4(最少出队人数)
      
  • 思路:这个题是求最长递增子序列的升级版,先正序求出最长递增子序列的长度,然后再求逆序最长递增子序列长度(看了别人的思路之后的理解,这种题目总是自己写不出来,看完别人的思路又觉得明白了)

  • 代码:
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        while(scan.hasNext()){
            int number = scan.nextInt();
            int[] inc = new int[number];
            int[] dec = new int[number];
            int[] value = new int[number];
            for(int i = 0; i < number; i++){
                value[i] = scan.nextInt();
                inc[i] = 1;
                dec[i] = 1;
            }

            for(int i = 1; i < number; i++){
               // inc[i] = 1;
                for(int j = 0; j < i; j++){
                    if(value[j] < value[i]){
                        inc[i] = Math.max(inc[i], inc[j] + 1);
                    }
                }
            }

            for(int i = number - 2; i >= 0; i--){
                //dec[i] 
                for(int j = number-1; j > i;j--){
                    if(value[j] < value[i]){
                        dec[i] = Math.max(dec[j] + 1, dec[i]);
                    }
                }
            }
            int temp = 0;
            for(int i = 0; i < number; i++){
                if(inc[i] + dec[i] - 1 > temp){
                    temp = inc[i] + dec[i] - 1;
                }
            }
            System.out.println(number - temp);
        }


    }
}

你可能感兴趣的:(华为在线编程系列-合唱队(动态规划的应用))