• 动态规划之合唱队形问题


    代码:

    麻烦的思路(java):

    import java.util.Scanner;
    
    //N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,而不改变其他同学的位置,使得剩下的K位同学排成合唱队形。
    //合唱队形要求:设K位同学从左到右依次编号为1,2…,K,他们的身高分别为T1,T2,…,TK,则他们的身高满足T1<T2...<Ti>Ti+1>…>TK(1<=i<=K)。
    //已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成最长的合唱队形。
    
    public class tutti {
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		int N = sc.nextInt();
    		int height[] = new int[N];
    		int maxNumber[] = new int[N];
    		int max = -1;
    		
    		for (int i = 0; i < N; i++) {
    			height[i] = sc.nextInt();
    		}
    		
    		for (int i = 0; i < N; i++) {
    			int m = -1;
    			left(i,height,maxNumber);
    			for (int j = 0; j <= i; j++) {
    				if(maxNumber[j]>m){
    					m = maxNumber[j];
    				}
    			}
    			int n = -1;
    			right(i,height,maxNumber);
    			for (int j = i; j < N; j++) {
    				if(maxNumber[j]>n){
    					n = maxNumber[j];
    				}
    			}
    			if((m+n-1)>max){
    				max = m+n-1;
    			}
    		}
    		System.out.println(max);
    	}
    
    	private static void right(int i, int[] height, int[] maxNumber) {
    		for (int j = i; j < height.length; j++) {
    			maxNumber[j] = 1;
    			for (int j2 = i; j2 < j; j2++) {
    				if((height[j]<=height[j2])&&(maxNumber[j2]+1>maxNumber[j])) maxNumber[j] = maxNumber[j2]+1;
    			}
    		}
    	}
    
    	private static void left(int i, int[] height, int[] maxNumber) {
    		for (int j = 0; j <= i; j++) {
    			maxNumber[j] = 1;
    			for (int j2 = 0; j2 < j; j2++) {
    				if((height[j]>=height[j2])&&(maxNumber[j2]+1>maxNumber[j])) maxNumber[j] = maxNumber[j2]+1;
    			}
    		}
    	}
    }
    

      简单的思路(java):

    public class test {  
        public static void main(String[] args) {  
            int []high={176,163,150,140,180,130,167,160};  
            int []up=new int[8];   //记录每位同学的最大上升子序列  
            int []down=new int[8]; //记录每位同学的最大下降子序列  
            for(int i=0;i<high.length;i++){  
                up[i]=1; //每位同学的最大上升子序列初始值为1  
                for(int j=0;j<i;j++){  
                    if((high[j]<high[i])&&(up[i]<up[j]+1)) up[i]=up[j]+1; //前i位同学的最大上升子序列的最大值再加1  
                }  
            }  
            for(int i=high.length-1;i>=0;i--){  
                down[i]=1;  
                for(int j=high.length-1;j>i;j--){  
                    if((high[j]<high[i])&&(down[i]<down[j]+1)) down[i]=down[j]+1; //后N-i位同学的最大下降子序列的最大值再加1  
                }  
            }  
            int max=0; //设每位同学所形成的最长合唱队形的最大值初值为0  
            int index=0; //设最大值对应的索引为0  
            for(int i=0;i<high.length;i++){  
                if(up[i]+down[i]-1>max) {  
                    max=up[i]+down[i]-1; //求得每位同学所形成的最长合唱队形的最大值  
                    index=i;  //求得对应的索引  
                }  
            }  
            System.out.println("最长合唱队形的长度为:"+max);  
            System.out.println("对应的是第"+(index+1)+"位同学,需要"+(high.length-max)+"位同学出列");  
      
        }  
    }  
    

      

  • 相关阅读:
    损失函数
    numpy中的broadcast
    混合模型
    贝叶斯学习
    python3中输出不换行
    C++11 实现 argsort
    Python中的闭包
    C语言 fread()与fwrite()函数说明与示例
    DFT与傅里叶变换的理解
    MISRA C:2012 Dir-1.1(只记录常犯的错误和常用的规则)Bit-fields inlineC99,NOT support in C90 #pragma
  • 原文地址:https://www.cnblogs.com/-rainbow-/p/7999305.html
Copyright © 2020-2023  润新知