Go: package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
)

type Matrix struct {
	r int // num of row
	c int // num of column
}

type Range struct {
	start int // index, inclusive
	end   int // index, inclusive
}

func calcMultiplication(x, y Matrix) (Matrix, int) {
	if x.c != y.r {
		panic("cannnot calculate")
	}
	return Matrix{x.r, y.c}, x.r * y.c * x.c
}

func calcMinMatrixChainMultiplication(matrices []Matrix, r Range, memo map[Range]int) (Matrix, int) {
	if v, ok := memo[r]; ok {
		return Matrix{matrices[0].r, matrices[len(matrices)-1].c}, v
	}
	if len(matrices) == 0 {
		panic("must not be empty")
	} else if len(matrices) == 1 {
		return matrices[0], 0
	} else if len(matrices) == 2 {
		return calcMultiplication(matrices[0], matrices[1])
	}

	var minCount int = math.MaxInt32

	for i := 0; i < len(matrices)-1; i++ {
		formerMatrices := matrices[:i+1]
		latterMatrices := matrices[i+1:]
		matF, countF := calcMinMatrixChainMultiplication(formerMatrices, Range{0, i}, memo)
		matL, countL := calcMinMatrixChainMultiplication(latterMatrices, Range{i + 1, len(matrices) - 1}, memo)
		_, countFL := calcMultiplication(matF, matL)
		count := countF + countL + countFL
		if count < minCount {
			minCount = count
		}
	}
	return Matrix{matrices[0].r, matrices[len(matrices)-1].c}, minCount
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	n, _ := nextInt(sc)
	matrices := make([]Matrix, n)
	for i := 0; i < n; i++ {
		r, _ := nextInt(sc)
		c, _ := nextInt(sc)
		matrices[i] = Matrix{r, c}
	}
	memo := make(map[Range]int)
	_, resultCount := calcMinMatrixChainMultiplication(matrices, Range{0, len(matrices) - 1}, memo)
	fmt.Println(resultCount)
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <queue>
#include <stack>
#include <tuple>
#include <cmath>
#include <iomanip>
#include <map>
#include <cstring> //memset(dp,0,sizeof(dp))
#include <functional>
#include <cctype>
#include <locale>
#define ll long long
#define rep(i,n) for(int i=0;i<(n);i++)
#define rrep(i,n) for(int i=n-1;i>=0;i--)
#define fi first
#define se second
#define pb push_back
#define ALL(a) (a).begin(),(a).end()
using namespace std;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}
typedef pair<int,int> P;
typedef pair<long long,long long> Pll;
#define fout(num) cout << fixed << setprecision(20) << (num) << endl
//s[i]=tolower(s[i]); islower(s[i]); cout << tolower(s[i])はバグ
//vector<vector<ll>> dp(n,vector<ll>(n))
//exist x map o setconst ll MOD = 1e9+7;return fac[n]*(finv[k]*finv[n-k] % MOD) % MOD;
const ll INF = 1e18;
signed main(){
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n; cin >> n;
    ll dp[n][n];
    rep(i,n)rep(j,n)dp[i][j]=INF;
    rep(i,n) dp[i][i]=0;
    ll c[n],r[n];
    rep(i,n){
        cin  >> r[i] >> c[i];
    }
    for(int num=2;num<=n;num++){
        for(int i=0;i<n;i++){
            int j=i+num-1;
            if(j<0||n<=j) continue;
            for(int k=i;k<j;k++){
                dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+r[i]*c[k]*c[j]);
            }
        }
    }
    cout<< dp[0][n-1]  << endl;
}

C++: #include <stdio.h>
#include <math.h>

int matrixChainMultiplication(int *);

int n;

int main(){
  int i,A[101],l,j,k;

  scanf("%d",&n);
  for(i=1;i<=n;i++){
    scanf("%d",&A[i-1]);
    scanf("%d",&A[i]);
  }
  printf("%d\n",matrixChainMultiplication(A));


}
int matrixChainMultiplication(int *A){
  int i,l,j,k,P[101][101],g;
  for(i=1;i<n;i++){
    P[i][i]=0;
  }
  for(l=2;l<=n;l++){
    for(i=1;i<=n-l+1;i++){
      j=i+l-1;
      P[i][j]=9999999;
      for(k=i;k<=j-1;k++){
	g=P[i][k]+P[k+1][j]+A[i-1]*A[k]*A[j];
	if(g<P[i][j])
	  P[i][j]=g;
	  
      }
    }
  }

  return P[1][n];
}