class Solution {
public int minCost(int n, int[] cuts) {
int[] extendedCuts = new int[cuts.length + 2];
int[][] mem = new int[extendedCuts.length][extendedCuts.length];
System.arraycopy(cuts, 0, extendedCuts, 1, cuts.length);
extendedCuts[0] = 0;
extendedCuts[extendedCuts.length - 1] = n;
Arrays.sort(extendedCuts);
Arrays.stream(mem).forEach(A -> Arrays.fill(A, Integer.MAX_VALUE));
return minCost(extendedCuts, 0, extendedCuts.length - 1, mem);
}
// Returns minCost(cuts[i..j]).
private int minCost(int[] cuts, int i, int j, int[][] mem) {
if (j - i <= 1)
return 0;
if (mem[i][j] != Integer.MAX_VALUE)
return mem[i][j];
for (int k = i + 1; k < j; ++k)
mem[i][j] = Math.min(mem[i][j],
cuts[j] - cuts[i] + minCost(cuts, i, k, mem) + minCost(cuts, k, j, mem));
return mem[i][j];
}
}