有 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
/**
* 数组存在负数,需要维护一个最小值mn[i][j]
* mx[i][j]表示前i个人选了j个人并且以第i个人为结尾满足相邻位置差不大于d的最大值
* mn[i][j]表示前i个人选了j个人并且以第i个人为结尾满足相邻位置差不大于d的最小值
*/
public class Main {
private static long solve(int[] arr, int n, int k, int d) {
long[][] mx = new long[n + 1][12];
long[][] mn = new long[n + 1][12];
long ans = Long.MIN_VALUE;
for (int i = 1; i <= n; i++) {
mx[i][1] = arr[i - 1];
mn[i][1] = arr[i - 1];
for (int j = 2; j <= k; j++) {
for (int x = i - 1; x >= Math.max(1, i - d); x--) {
long t_mx = mx[x][j - 1] * arr[i - 1];
long t_mn = mn[x][j - 1] * arr[i - 1];
mx[i][j] = Math.max(mx[i][j], Math.max(t_mx, t_mn));
mn[i][j] = Math.min(mn[i][j], Math.min(t_mx, t_mn));
}
}
ans = Math.max(ans, mx[i][k]);
}
return ans;
}
public static void main(String[] arg) {
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
int n = scan.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = scan.nextInt();
}
int k = scan.nextInt();
int d = scan.nextInt();
System.out.println(solve(arr, n, k, d));
}
scan.close();
}
}