Java蓝桥杯试题集——算法训练ALGO-116——最大的算式
题目要求
解题思路
动态规划,今天才弄明白QAQ,借鉴了这位大佬的博客,曹磊的博客 写的很好!但是我觉得我的循环方式更容易理解嘿嘿嘿~
首先建立如下图的数组,行数代表前几位数,列数代表有几个乘号。将第0列赋值为前i个数的和。(没有*号,全是+号,比如第4行就是前4个数的和)
然后从第1列开始循环,*至少要在第二个数字之前出现,所以index=2。第一列应该是所有有1个*的最大值。求的方法也很简单:
dp[2][1]就是1*2,这个2就是dp[2][0] - dp[1][0]得来的。
dp[3][1]的求解循环了2遍,当 1*(2+3),和当(1+2)*3。选取结果最大的那个。
当有两个*时:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
long[][] dp = new long[n + 1][k + 1]; // 第0行不用,这里使用long
int i, j, index;
for (i = 1; i <= n; i++) {
dp[i][0] = dp[i - 1][0] + in.nextInt(); // 初始化第0列数组,是没有乘号的情况下的最大值(和)
}
for (j = 1; j <= k; j++) { // 列数
for (i = j + 1; i <= n; i++) { // 行数
for (index = 2; index <= i; index++) { // 第几个值前面有*
dp[i][j] = Math.max(dp[i][j], dp[index - 1][j - 1] * (dp[i][0] - dp[index - 1][0]));
}
}
}
System.out.println(dp[n][k]);
}
}