import java.util.*; public class MatrixChainMultiply { public static int solveIterative(int[] s) { int n = s.length - 1; int[][] p = new int[n][n]; int[][] m = new int[n][n]; for (int len = 2; len <= n; len++) { for (int a = 0; a + len <= n; a++) { int b = a + len - 1; m[a][b] = Integer.MAX_VALUE; for (int c = a; c < b; c++) { int v = m[a][c] + m[c + 1][b] + s[a] * s[c + 1] * s[b + 1]; if (m[a][b] > v) { m[a][b] = v; p[a][b] = c; } } } } return m[0][n - 1]; } public static int solveRecursive(int[] s) { int n = s.length - 1; int[][] cache = new int[n][n]; for (int[] x : cache) Arrays.fill(x, INF); int[][] p = new int[n][n]; return rec(0, n - 1, s, p, cache); } static final int INF = Integer.MAX_VALUE / 3; static int rec(int i, int j, int[] s, int[][] p, int[][] cache) { if (i == j) return 0; int res = cache[i][j]; if (res != INF) return res; for (int k = i; k < j; k++) { int v = rec(i, k, s, p, cache) + rec(k + 1, j, s, p, cache) + s[i] * s[k + 1] * s[j + 1]; if (res > v) { res = v; p[i][j] = k; } } return cache[i][j] = res; } // test public static void main(String[] args) { Random rnd = new Random(1); for (int step = 0; step < 1000; step++) { int n = rnd.nextInt(6) + 2; int[] s = rnd.ints(n, 1, 11).toArray(); int res1 = solveIterative(s); int res2 = solveRecursive(s); if (res1 != res2) { System.out.println(res1 + " " + res2); System.out.println(Arrays.toString(s)); } } } }