华为 OJ --- 合唱队 java

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

说明:

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


源码

  1. import java.util.Scanner;  
  2.   
  3. public class Main {  
  4.   
  5.     public static void main(String[] args) {  
  6.         // TODO Auto-generated method stub  
  7.         Scanner cScanner = new Scanner(System.in);  
  8.         int len = cScanner.nextInt();  
  9.         int[] team = new int[len];    
  10.         for(int i=0; i<len; i++){  
  11.             team[i] = cScanner.nextInt();  
  12.         }  
  13.         System.out.println(len - dblLis(team));  
  14.   
  15.         cScanner.close();  
  16.     }  
  17.       
  18.     public static int lis(int[] seq){  
  19.                 //LIS算法供参考理解              
  20.       
  21.         //data[i][0]:N,data[i][1]:lis_len,data[i][2]:next_index  
  22.         int[][] data = new int[seq.length][2];  
  23.         data[0][0] = seq[0];  
  24.         data[0][1] = 1;  
  25.           
  26.         for(int i=1; i<seq.length; i++){  
  27.             data[i][0] = seq[i];  
  28.             for(int j=i-1; j>=0; j--){  
  29.                 if(seq[i]>=data[j][0]){  
  30.                     data[i][1] = data[j][1]+1;  
  31.                     break;  
  32.                 }  
  33.             }  
  34.               
  35.             //No sequence  
  36.             if(data[0][1] == 0){  
  37.                 data[0][1] = 1;  
  38.             }  
  39.         }  
  40.           
  41.           
  42.         int maxLis = 0;  
  43.         for(int i=0; i<data.length; i++){  
  44.             if(data[i][1] > maxLis){  
  45.                 maxLis = data[i][1];  
  46.             }  
  47.         }  
  48.           
  49.         return maxLis;  
  50.     }  
  51.       
  52.     public static int dblLis(int[] seq){  
  53.           
  54.         //data[i][0]:N,data[i][1]:lis_len,data[i][2]:next_index  
  55.         int[][] data = new int[seq.length][3];  
  56.         data[0][0] = seq[0];  
  57.         data[0][1] = 1;  
  58.         data[seq.length-1][2] = 1;  
  59.           
  60.         int tmpMax = 1;  
  61.         for(int i=1; i<seq.length; i++){  
  62.             tmpMax = 1;  
  63.             data[i][0] = seq[i];  
  64.             for(int j=i-1; j>=0; j--){  
  65.                 if(seq[i]>data[j][0] && data[j][1]+1 > tmpMax){  
  66.                     tmpMax = data[j][1]+1;  
  67.                 }  
  68.             }  
  69.               
  70.             data[i][1] = tmpMax;  
  71.         }  
  72.           
  73.         for(int i=seq.length-2; i>=0; i--){  
  74.             tmpMax = 1;  
  75.             data[i][0] = seq[i];  
  76.             for(int j=i+1; j<seq.length; j++){  
  77.                 if(seq[i]>data[j][0] &&  data[j][2]+1 > tmpMax){  
  78.                     tmpMax = data[j][2]+1;  
  79.                 }  
  80.             }  
  81.               
  82.             data[i][2] = tmpMax;  
  83.         }  
  84.           
  85.         int maxDblLis = 0;  
  86.         for(int i=0; i<data.length; i++){  
  87.             //System.out.println(data[i][1] + "," + data[i][2]);  
  88.             if(data[i][1]+data[i][2] > maxDblLis){  
  89.                 maxDblLis = data[i][1]+data[i][2];  
  90.             }  
  91.         }  
  92.           
  93.         return maxDblLis-1;  
  94.     }  
  95.   

答案


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值