合唱队

/*

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

知识点	循环
运行时间限制	0M
内存限制	0
输入	
整数N
一行整数,空格隔开,N位同学身高

输出	
最少需要几位同学出列
样例输入	8 186 186 150 200 160 130 197 200
样例输出	4
*/
import java.util.Scanner;  
  
public class Main {  
  
    public static void main(String args[])  
    {  
        Scanner input = new Scanner(System.in);  
        Main main = new Main();  
          
        int num = input.nextInt();  
        int[] high = new int[num];  
          
        for(int i = 0;i < num;i++)  
        {  
            high[i] = input.nextInt();  
  
        }  
        input.close();  
          
        System.out.println(num - main.LIS(high));  
    }  
      
    int LIS(int[] high)  
    {  
        int i,maxNum = 0,leg = high.length;  
          
        int[] asc = new int[leg];  
        int[] desc = new int[leg];  
          
        asc = this.getAsc(high);  
        desc = this.getDesc(high);  
          
        for(i = 0; i < leg;i++)  
        {  
            if(maxNum < asc[i] + desc[i])  
                maxNum = asc[i] + desc[i];  
        }  
        return maxNum-1;  
    }  
      
    int[] getAsc(int[] high)  
    {  
        int leg = high.length;  
        int[] asc = new int[leg];  
        for(int i = 0;i < leg;i++)  
        {  
            asc[i] = 1;  
        }  
        for(int i = 1;i < leg;i++)  
        {  
            for(int j = 0; j < i;j++)  
            {  
                if((high[j] < high[i]) && (asc[i] < asc[j]+1 ))  
                {  
                    asc[i] = asc[j]+1;  
                }  
            }  
        }  
          
        return asc;  
    }  
      
    int[] getDesc(int[] high)  
    {  
        int leg = high.length;  
        int[] desc = new int[leg];  
          
        for(int i = 0;i < leg;i++)  
        {  
            desc[i] = 1;  
        }  
          
        for(int i = leg - 2;i > 0;i--)  
        {  
            for(int j = leg - 1; j > i;j--)  
            {  
                if((high[j] < high[i]) && (desc[i] < desc[j]+1 ))  
                {  
                    desc[i] = desc[j]+1;  
                }  
            }  
        }  
          
        return desc;  
    }  
}  
这个主要用到的是动态规划,不懂得可以百度啊……
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值