1.代码
public class MatrixChainMultiplication {
public static void main(String[] args) {
// 在该代码中,我们首先创建了两个n * n的矩阵m和s,分别用于记录最优值和分割点。 其中m 矩阵 通过i j 来显示在i到j的矩阵链中最优解
//
// 然后,我们将i = j时的m[i][j]赋值为0,因为一个矩阵的乘积为0。
//
// 接下来,我们使用L循环枚举子问题规模,i循环枚举左端点,j循环枚举右端点,并使用k循环枚举分割点。
//
// 对于每个分割点k,我们计算最优值q,然后将q与m[i][j]进行比较,如果q小于m[i][j],则更新m[i][j]和s[i][j]。
// 通过公式算法导论15.7
//
// 最后,我们返回m[1][n-1],即原问题的最优值。
//
// 该算法的时间复杂度为O(n^3),其中n是矩阵的数量。
int[] p = {30, 35, 15, 5, 10, 20, 25};
System.out.println("最少的乘法次数为:" + matrixChainOrder(p));
}
public static int matrixChainOrder(int[] p) {
int n = p.length;
// 创建n * n的矩阵m和s,用于记录最优值和分割点
int[][] m = new int[n][n];
int[][] s = new int[n][n];
// i==j时,m[i][j]=0,因为一个矩阵的乘积为0
for (int i = 1; i < n; i++) {
m[i][i] = 0;
}
for (int i = 0; i < m.length; i++) {
System.out.println(Arrays.toString(m[i]));
}
// L是子问题规模
for (int L = 2; L < n; L++) {
// i是左端点,j是右端点,k是分割点
for (int i = 1; i < n - L + 1; i++) {
int j = i + L - 1;
m[i][j] = Integer.MAX_VALUE;
// 枚举分割点k,求解最优值
for (int k = i; k < j; k++) {
int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
System.out.println("m[i][k]: "+m[i][k] );
System.out.println("m[k + 1][j]: "+m[k + 1][j]);
System.out.println("i:"+i+" k:"+k+" j:"+j);
System.out.println(q);
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
// 返回最优值
return m[1][n - 1];
}
}
2.原理
自己看算法导论吧

我再看到

这条公式的时候很困惑,然后自己手算了他给的第一个例子才知道这是正确的.
3.问题
具体的问题已经在代码注释中讲解完毕
4.进阶
输出只是I一个普通的递归而已
package collection;
public class printOptimalParens {
public static void matrixChainOrder(int[] p) {
int n = p.length - 1;
int[][] m = new int[n + 1][n + 1];
int[][] s = new int[n + 1][n + 1];
for (int i = 1; i <= n; i++) {
m[i][i] = 0;
}
for (int len = 2; len <= n; len++) {
for (int i = 1; i <= n - len + 1; i++) {
int j = i + len - 1;
m[i][j] = Integer.MAX_VALUE;
for (int k = i; k <= j - 1; k++) {
int q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
System.out.println("Optimal Parenthesization:");
printOptimalParens(s, 1, n);
}
public static void printOptimalParens(int[][] s, int i, int j) {
if (i == j) {
System.out.print("A" + i);
} else {
System.out.print("(");
printOptimalParens(s, i, s[i][j]);
printOptimalParens(s, s[i][j] + 1, j);
System.out.print(")");
}
}
public static void main(String[] args) {
int[] p = {30, 35, 15, 5, 10, 20, 25};
matrixChainOrder(p);
}
}
((A1(A2A3))((A4A5)A6))



















