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
	}

	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
		}
	}
	memo[r] = minCount
	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 <stdio.h>
const int N=110;
const int INF=1<<30;
int min(int a,int b){
    return a>b?b:a;
}
int main(){
    int n,dp[N][N],a[N];
    scanf("%d%d%d",&n,&a[0],&a[1]);
    for(int i=1;i<n;i++)scanf("%d%d",&a[i],&a[i+1]);
    for(int k=1;k<n;k++){
        for(int i=0;i<n-k;i++){
            dp[i][i+k]=INF;
            for(int j=i;j<i+k;j++)dp[i][i+k]=min(dp[i][i+k],dp[i][j]+dp[j+1][i+k]+a[i]*a[j+1]*a[i+k+1]);
        }
    }
    printf("%d\n",dp[0][n-1]);
}

C++: #include<iostream>
#include<algorithm>

using namespace std;

int main  () {

    int i, j, k, l, n, p[101], m[101][101];

    cin >> n;

    for (i = 1; i <= n; i++) {
        cin >> p[i - 1] >> p[i];
    }

    for (i = 1; i<= n; i++) {
        m[i][i] = 0;
    }

    for (l = 2; l <= n; l++) {
        for (i = 1; i <= n - l+ 1; i++) {
            j = i + l - 1;
            m[i][j] = (1 << 21);

            for (k = i; k <=j - 1; k++) {
                m[i][j] = min (m[i][j], m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j]);
            }
        }
    }

    cout << m[1][n] << endl;

    return 0;

}

C++: #include <stdio.h>
#include <algorithm>
using namespace std;
int n, r[100], c[100], dp[100][101];
int main() {
	scanf("%d", &n);
	for(int i = 0; i < n; i++) scanf("%d%d", &r[i], &c[i]), dp[i][i] = 0;
	for(int i = 1; i < n; i++) {
		for(int j = 0; i + j <= n; j++) {
			dp[j][i + j] = min(dp[j][i + j - 1], dp[j + 1][i + j]) + c[j] * c[i + j - 1];
		}
	}
	printf("%d\n", dp[0][n]);
	return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;

// macro
#define rep(i,n) for(i=0;i<n;i++)
#define ll long long
#define all(v) v.begin(), v.end()

// code starts
#define INF 1020304050

int main()
{
  int n;cin>>n;
  vector<int> r(n);
  vector<int> c(n);
  int i,j,k;
  rep(i,n)cin>>r[i]>>c[i];
  vector<vector<int>> dp(n,vector<int>(n,INF));
  rep(i,n)dp[i][i]=0;
  rep(i,n-1)dp[i][i+1]=r[i]*c[i]*c[i+1];
  for(i=2;i<n;i++)
  {
    rep(j,n-i)
    {
      for(k=1;k<=i;k++)
      {
        dp[j][j+i]=min(dp[j][j+i],dp[j][j+k-1]+dp[j+k][j+i]+r[j]*r[j+k]*c[j+i]);
      }
    }
  }
  cout<<dp[0][n-1]<<endl;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
static const int N = 100;
int main() {
    int n, p[N + 1], m[N + 1][N + 1];
    cin >> n;
 
    for (int i = 1; i <= n; i++)cin >> p[i - 1] >> p[i];
 
    for (int i = 1; i <= n; i++)m[i][i] = 0;
 
    for (int l = 2; l <= n; l++) {
        for (int i = 1; i <= n - l + 1; i++) {
            int j = i + l - 1;
            m[i][j] = (1 << 21);
            for (int k = i; k < j; k++) {
                m[i][j] = min(m[i][j], m[i][k] +  m[k + 1][j] + p[i - 1] * p[k] * p[j]);
            }
        }
    }
    cout << m[1][n] << endl;
    return 0;
}

C++: #include <iostream>
#include <algorithm>
const int MAX_N = 100;
const int INF = 114514;
using namespace std;

int dp[MAX_N+1][MAX_N+1];
int p[MAX_N+1];

int main(void) {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        dp[i][i] = 0;
    }
    for (int i = 1; i <= n; i++) {
        cin >> p[i-1] >> p[i];
    }

    for (int l = 2; l <= n; l++) {
        for (int i = 1; i <= n; i++) {
            int j = i + l - 1;
            dp[i][j] = INF;
            for (int k = i; k <= j - 1; k++) {
                dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j] + p[i-1]*p[k]*p[j]);
            }
        }
    }

    cout << dp[1][n] << endl;

    return 0;
}