public class Main {
public static void main(String[] args) {
Main main = new Main();
p[] p = {new p(30,35), new p(35, 15),new p(15,5),new p(5,10),new p(10,20),new p(20,25),};
m_s m_s=main.MATRIX_CHAIN_ORDER(p);
System.out.println(m_s.m[1][6]);
main.PRINT_OPTIMAL_PARTS_TO_STRING(m_s.s, 1, 6);
}
static class p{
int p1;
int p2;
int P[][];
public p(int p1, int p2) {
this.p1 = p1;
this.p2 = p2;
}
public p(int p1, int p2,int [][]P) {
this.p1 = p1;
this.p2 = p2;
this.P = P;
}
}
class m_s {
int m[][];
int s[][];
public m_s(int m[][], int s[][]) {
this.m = m;
this.s = s;
}
}
public int[][] MATRIX_CHAIN_MULTIPLY(p[] p, int s[][], int i, int j) {
if (i==j) return p[i].P;
else if (i==j-1) return MATRIX_MULTIPLY(p[i].P, p[j].P);
int[][] A = MATRIX_CHAIN_MULTIPLY(p, s, i, s[i][j]);
int[][] B = MATRIX_CHAIN_MULTIPLY(p, s, s[i][j] + 1, j);
return MATRIX_MULTIPLY(A, B);
}
public int[][] MATRIX_MULTIPLY(int[][] A, int[][] B) {
if (A[0].length!=B.length) {
System.out.println("输入错误!");
return null;
}
int p = A[0].length;
int n = A.length;
int m = B[0].length;
int C[][] = new int[A.length][B[0].length];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int curr = 0;
for (int k = 0; k < p; k++) {
curr = curr + A[i][k] * B[k][j];
}
C[i][j] = curr;
}
}
return C;
}
public m_s MATRIX_CHAIN_ORDER(p[] p) {
int[][] m = new int[p.length + 1][p.length + 1];
int[][] s = new int[p.length][p.length + 1];
for (int l = 2; l <= p.length; l++) {
for (int i = 1; i <= p.length - l+1; i++) {
int j = i + l - 1;
m[i][j] = Integer.MAX_VALUE;
for (int k = i; k < j; k++) {
int q = m[i][k] + m[k + 1][j] + p[i-1].p1 * p[k-1].p2 * p[j-1].p2;
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
}
}
return new m_s(m, s);
}
public void PRINT_OPTIMAL_PARTS_TO_STRING(int[][] s, int i, int j) {
if (i==j) System.out.print("A" + i);
else {
System.out.print("(");
PRINT_OPTIMAL_PARTS_TO_STRING(s, i, s[i][j]);
PRINT_OPTIMAL_PARTS_TO_STRING(s, s[i][j] + 1, j);
System.out.print(")");
}
}
}