网易_合唱团 简单动态规划

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37667021/article/details/82258889

网易_合唱团

题目描述

有 n 个学生站成一排,每个学生有一个能力值,牛牛想从这 n 个学生中按照顺序选取 k 名学生,要求相邻两个学生的位置编号的差不超过 d,使得这 k 个学生的能力值的乘积最大,你能返回最大的乘积吗?

输入描述:

每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50),表示学生的个数,接下来的一行,包含 n 个整数,按顺序表示每个学生的能力值 ai(-50 <= ai <= 50)。接下来的一行包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。

输出描述:

输出一行表示最大的乘积。

输入

3
7 4 7
2 50

输出

49

思路如下:

要求是从一个数组中顺序挑选出k个数,使得这k个数之乘积最大,但这k个数在数组中的位置编号的差不超过 d。

可以用maxVal[i][j]表示以j位置上的数为选的最后一个数,选择i个数的时候的最大值。这个题可以这样想,假如正在选第i个数,那么 maxVal[i][j]=ability[j]*maxVal[i-1][m],因为maxVal[i][j]本身就以j位置上的数为最后一个数,即j上面的必选,然后再乘上以前第i-1次时的结果就是现在的结果。第i个数时j上的数,那么第i-1个数就是从j位置向前推的距离不超过d的这些数其中一个,所以递推公式应该是  maxVal[i][j]=Math.max(maxVal[i][j], ability[j]*maxVal[i-1][m]);m表示着距离j不超过d的中的一个。由于数组中存在负数,那么我们不仅仅需要记录最大值,还要记录最小值, minVal[i][j]=Math.min(minVal[i][j], ability[j]*minVal[i-1][m]);

解释一下这个for循环: 

for(i=2;i<=n;++i) {
    for(j=0;j<n;++j) {
         start=j-d;
         if(start<0)start=0;
         for(m=j-1;m>=start;m--){.....}
    }
}

第一层先是确定找第i个数,第i个数的范围是0到n-1,即确定选的最后一个数是j,然后这 minVal[i][j] 的最大值由第 个上的数乘以选择的第i-1个数决定,故第3层循环是j前的d个数,可以从前往后遍历,也可以从后往前遍历,没有区别,因为ability[j]*minVal[i-1][m]中乘的是i-1层的数。以下这两个代买只是循环顺序不一样,只是为了理解才写的

代码一:

import java.util.*;
public class Main {
    public static void main(String args[]) {
         
        int i,j,k,n,d,m;
        int[]ability=new int[60];
        Scanner cin=new Scanner(System.in);
        int start;
        while(cin.hasNextInt()) {
            n=cin.nextInt();
            for(i=0;i<n;++i)
                ability[i]=cin.nextInt();
             
            k=cin.nextInt();
            d=cin.nextInt();
             
             
            long [][]maxVal=new long[60][60];
            long[][]minVal=new long[60][60];
            long ans=0;
            for(i=0;i<n;++i) {
                maxVal[1][i]=ability[i];
                ans=Math.max(ans,ability[i]);
                minVal[1][i]=ability[i];
                 
            }
            for(i=2;i<=n;++i) {
                for(j=0;j<n;++j) {
                    start=j-d;
                    if(start<0)start=0;
                    for(m=j-1;m>=start;m--)
                    {
                        maxVal[i][j]=Math.max(maxVal[i][j], ability[j]*maxVal[i-1][m]);
                        maxVal[i][j]=Math.max(maxVal[i][j], ability[j]*minVal[i-1][m]);
                         
                        minVal[i][j]=Math.min(minVal[i][j], ability[j]*minVal[i-1][m]);
                        minVal[i][j]=Math.min(minVal[i][j], ability[j]*maxVal[i-1][m]);
                    }
                    if(i==k)ans=Math.max(ans,maxVal[k][j]);
                     
                }  
            }
             
            System.out.println(ans);
             
        }
         
         
    }
     
     
 
}
/*
36
7 -15 31 49 -44 35 44 -47 -23 15 -11 10 -21 10 -13 0 -20 -36 22 -13 -39 -39 -31 -13 -27 -43 -6 40 5 -47 35 -8 24 -31 -24 -1
3 31
  
  
 */

代码二:

import java.util.*;
public class Main {
	public static void main(String args[]) {
		
		int i,j,k,n,d,m;
		int[]ability=new int[60];
		Scanner cin=new Scanner(System.in);
		int start;
		while(cin.hasNextInt()) {
			n=cin.nextInt();
			for(i=0;i<n;++i)
				ability[i]=cin.nextInt();
			
			k=cin.nextInt();
			d=cin.nextInt();
			
			
			long [][]maxVal=new long[60][60];
			long[][]minVal=new long[60][60];
			long ans=0;
			for(i=0;i<n;++i) {
				maxVal[1][i]=ability[i];
				ans=Math.max(ans,ability[i]);
				minVal[1][i]=ability[i];
			    
			}
			for(i=2;i<=n;++i) {
				for(j=0;j<n;++j) { 
					start=j-d;
					if(start<0)start=0;
					for(m=start;m<=j-1;m++)
					{
						maxVal[i][j]=Math.max(maxVal[i][j], ability[j]*maxVal[i-1][m]);
						maxVal[i][j]=Math.max(maxVal[i][j], ability[j]*minVal[i-1][m]);
						
						minVal[i][j]=Math.min(minVal[i][j], ability[j]*minVal[i-1][m]);
						minVal[i][j]=Math.min(minVal[i][j], ability[j]*maxVal[i-1][m]);
					}
					if(i==k)ans=Math.max(ans,maxVal[k][j]);
					
				}	
			}
			
			System.out.println(ans);
			
		}
		
		
	}
	
	

}
/*
3
7 4 7
2 50

47
-41 -5 -10 -31 -44 -16 -3 -33 -34 -35 -44 -44 -25 -48 -16 -32 -37 -8 -33 -30 -6 -18 -26 -37 -40 -30 -50 -32 -5 -41 -32 -12 -33 -22 -14 -34 -1 -41 -45 -8 -39 -27 -23 -45 -10 -50 -34 
6 3

 
 
 */

猜你喜欢

转载自blog.csdn.net/m0_37667021/article/details/82258889
今日推荐