计算最少出列多少位同学,使得剩下的同学排成合唱队形
说明:
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。
合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK, 则他们的身高满足存在i(1<=i<=K)使得Ti<T2<......<Ti-1<Ti>Ti+1>......>TK。
你的任务是,已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
源码
- import java.util.Scanner;
- public class Main {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- Scanner cScanner = new Scanner(System.in);
- int len = cScanner.nextInt();
- int[] team = new int[len];
- for(int i=0; i<len; i++){
- team[i] = cScanner.nextInt();
- }
- System.out.println(len - dblLis(team));
- cScanner.close();
- }
- public static int lis(int[] seq){
- //LIS算法供参考理解
- //data[i][0]:N,data[i][1]:lis_len,data[i][2]:next_index
- int[][] data = new int[seq.length][2];
- data[0][0] = seq[0];
- data[0][1] = 1;
- for(int i=1; i<seq.length; i++){
- data[i][0] = seq[i];
- for(int j=i-1; j>=0; j--){
- if(seq[i]>=data[j][0]){
- data[i][1] = data[j][1]+1;
- break;
- }
- }
- //No sequence
- if(data[0][1] == 0){
- data[0][1] = 1;
- }
- }
- int maxLis = 0;
- for(int i=0; i<data.length; i++){
- if(data[i][1] > maxLis){
- maxLis = data[i][1];
- }
- }
- return maxLis;
- }
- public static int dblLis(int[] seq){
- //data[i][0]:N,data[i][1]:lis_len,data[i][2]:next_index
- int[][] data = new int[seq.length][3];
- data[0][0] = seq[0];
- data[0][1] = 1;
- data[seq.length-1][2] = 1;
- int tmpMax = 1;
- for(int i=1; i<seq.length; i++){
- tmpMax = 1;
- data[i][0] = seq[i];
- for(int j=i-1; j>=0; j--){
- if(seq[i]>data[j][0] && data[j][1]+1 > tmpMax){
- tmpMax = data[j][1]+1;
- }
- }
- data[i][1] = tmpMax;
- }
- for(int i=seq.length-2; i>=0; i--){
- tmpMax = 1;
- data[i][0] = seq[i];
- for(int j=i+1; j<seq.length; j++){
- if(seq[i]>data[j][0] && data[j][2]+1 > tmpMax){
- tmpMax = data[j][2]+1;
- }
- }
- data[i][2] = tmpMax;
- }
- int maxDblLis = 0;
- for(int i=0; i<data.length; i++){
- //System.out.println(data[i][1] + "," + data[i][2]);
- if(data[i][1]+data[i][2] > maxDblLis){
- maxDblLis = data[i][1]+data[i][2];
- }
- }
- return maxDblLis-1;
- }
- }