Finding optimal multiplication order and optimal binary tree
This is the classic problem of matrix chain multiplication. 

Here is the pseudocode in Java from Wikipedia, which computes, for each $2 \le k \le n$, the minimum costs of all subsequences of length k using the costs of smaller subsequences already computed. It runs in $O(n^3)$, where $n$ is is the number of matrices, assuming the number of rows and columns in all matrices are bounded by a constant.

// Matrix A[i] has dimension dims[i-1] x dims[i] for i = 1..n
// The first index for dims is 0 and the first index for m and s is 1.
MatrixChainOrder(int dims[])
{
    // length[dims] = n + 1
    n = dims.length - 1;
    // m[i,j] = Minimum number of scalar multiplications (i.e., cost)
    // needed to compute the matrix A[i]A[i+1]...A[j] = A[i..j]
    // The cost is zero when multiplying one matrix
    for (i = 1; i &lt;= n; i++)
        m[i, i] = 0;

    for (len = 2; len &lt;= n; len++) { // Subsequence lengths
        for (i = 1; i &lt;= n - len + 1; i++) {
            j = i + len - 1;
            m[i, j] = MAXINT;
            for (k = i; k &lt;= j - 1; k++) {
                cost = m[i, k] + m[k+1, j] + dims[i-1]*dims[k]*dims[j];
                if (cost &lt; m[i, j]) {
                    m[i, j] = cost;
                    s[i, j] = k; // Index of the subsequence split that achieved minimal cost
                }
            }
        }
    }
}


You can check that Wikipedia page for more information. In particular, there is a ready-make java implementation. There is also explanation to a much more complicated algorithm that runs in $O(n\log n)$ time.