首页 > 试题广场 >

排队问题

[编程题]排队问题
  • 热度指数:383 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解

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


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


输出描述:
输出一行表示最大的乘积
示例1

输入

3
7 4 7
2 50

输出

49
import java.util.Arrays;
import java.util.Scanner;

/**
* @Description:有n个学生站成一排,
 * 每个学生有一个能力值,
 * 牛牛想从这n个学生中按照顺序选取k名学生,
 * 要求相邻两个学生的位置编号的差不超过d,
 * 使得这k个学生的能力值的乘积最大,你能返回最大的乘积吗?
* @Create: 2020/4/16 15:47
* @Version: 1.0
*/
public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        int ai[] = new int[n];
        for (int i = 0; i < ai.length; i++) {
            ai[i] = input.nextInt();
        }
        int k = input.nextInt();
        int d = input.nextInt();


        int[] dp = new int[n];
        for (int i = 0; i < n; i++) {
            dp[i] = ai[i];
        }
        for (int i = 1; i < k; i++) {
            int[] dp2 = new int[n];
            Arrays.fill(dp2, Integer.MIN_VALUE);
            for (int j = 0; j < n; j++) {
                if (j - d >= 0) {
                    for (int j2 = j - d; j2 < j; j2++) {
                        dp2[j] = Math.max(dp2[j], ai[j] * dp[j2]);
                    }
                } else {
                    for (int j2 = 0; j2 < j; j2++) {
                        dp2[j] = Math.max(dp2[j], ai[j] * dp[j2]);
                    }
                }
            }
            dp = dp2;
           
        }
        int res = Integer.MIN_VALUE;
        for (int i = 0; i < n; i++) {
            res = Math.max(res, dp[i]);
        }
        System.out.println(res);
    }
}

模仿老哥的做法,只是我换了换了一维数组,降低空间复杂度。动态规划一般都是两层for+条件判断,最难的是想递推公式,也是条件判断
发表于 2020-04-16 16:55:24 回复(0)