Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func nextString() string {
	scanner.Scan()
	return scanner.Text()
}

func nextInt() int {
	n, err := strconv.Atoi(nextString())
	if err != nil {
		fmt.Printf("strconv.Atoi failed: %v\n", err)
	}
	return n
}

func min(x, y int) int {
	if x < y {
		return x
	}
	return y
}

func stringifyArray(arr []int) string {
	return strings.TrimRight(fmt.Sprintf("%+v", arr)[1:], "]")
}

func main() {
	scanner.Split(bufio.ScanWords)

	n := nextInt()
	m := make([][]int, n)
	sizes := make([][]int, n)
	for i := 0; i < n; i++ {
		sizes[i] = []int{nextInt(), nextInt()}
		m[i] = make([]int, n)
	}
	// fmt.Println(sizes)

	for w := 1; w < n; w++ {
		for i := 0; i < n-w; i++ {
			j := i + w
			minBetweenIandJ := 10000000
			for k := i; k < j; k++ {
				// fmt.Println(i, j, k, m[i][k], m[k+1][j], sizes[i][0]*sizes[k][1]*sizes[j][1])
				minBetweenIandJ = min(minBetweenIandJ, m[i][k]+m[k+1][j]+sizes[i][0]*sizes[k][1]*sizes[j][1])
			}
			m[i][j] = minBetweenIandJ
		}
	}
	// for i := 0; i < len(m); i++ {
	// 	fmt.Println(stringifyArray(m[i]))
	// }
	fmt.Println(m[0][n-1])
}

C++: #include <cassert>
// #include <algorithm>
#include <iostream>
#include <vector>
#include <climits>

struct TSize
{
    int r;
    int c;
    TSize() : r(0), c(0) {}
    TSize(int Ar, int Ac)
     : r(Ar), c(Ac)
    {}
};

class TMcmSolver
{
    typedef std::vector<std::vector<int> > TMatrix;
    TMatrix FMemo;
    const std::vector<TSize>& FChain;

    static int Count(const TSize& Left, const TSize& Right)
    {
        return Left.r * Right.c * Left.c;
    }
    int Solve(int s, int l)
    {
        assert(s <= l);
        if(s == l) return 0;
        if(FMemo[s][l] != 0) return FMemo[s][l];
        if(s + 1 == l){
            FMemo[s][l] = Count(FChain[s], FChain[l]);
        }else{
            int min = INT_MAX;
            for(int i = s+1; i < l; ++i){
                int c = Solve(s, i) + Count(TSize(FChain[s].r, FChain[i].c), TSize(FChain[i+1].r, FChain[l].c)) + Solve(i+1, l);
                min = std::min(min, c);
            }
            FMemo[s][l] = min;
        }
        return FMemo[s][l];
    }
public:
    TMcmSolver(const std::vector<TSize>& Chain)
     : FChain(Chain)
    {
        FMemo.resize(Chain.size());
        for(std::size_t i = 0; i < FMemo.size(); ++i){
            FMemo[i].resize(Chain.size(), 0);
        }
    }
    int Answer()
    {
        return Solve(0, FMemo.size()-1);
    }
    void Print()const
    {
        for(std::size_t s = 0; s < FMemo.size(); ++s){
            for(std::size_t l = 0; l < FMemo[0].size(); ++l){
                std::cout << FMemo[s][l] << '\t';
            }
            std::cout << '\n';
        }
    }
};

int main()
{
    int n;
    std::cin >> n;
    if(n == 1){
        std::cout << 0 << std::endl;
        return 0;
    }
    std::vector<TSize> Chain(n);
    for(int i = 0; i < n; ++i){
        std::cin >> Chain[i].r >> Chain[i].c;
    }
    TMcmSolver Solver(Chain);
    
    std::cout << Solver.Answer() << std::endl;
    // Solver.Print();
    return 0;
}

C++: #include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
typedef pair<ll, ll> pll;

#define FOR(i, n, m) for(ll (i)=(m);(i)<(n);++(i))
#define REP(i, n) FOR(i,n,0)
#define OF64 std::setprecision(10)

const ll MOD = 1000000007;
const ll INF = (ll) 1e15;

ll dp[105][105];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll N;
    cin >> N;
    vector<pll> A(N);
    REP(i, N) {
        cin >> A[i].first >> A[i].second;
    }

    REP(i, N + 1) {
        REP(j, N + 1) {
            dp[i][j] = INF;
        }
        dp[i][i] = 0;
    }

    FOR(len, N, 1) {
        REP(left, N) {
            if (left + len >= N)
                break;
            REP(i, len) {
                ll mul = dp[left][left + i] + dp[left + i + 1][left + len];
                mul += A[left].first * A[left + i].second * A[left + len].second;
                dp[left][left + len] = std::min(dp[left][left + len], mul);
            }
        }
    }

    cout << dp[0][N - 1] << endl;
    return 0;
}

C++: #include<iostream>
#include<vector>
#include<utility>
using namespace std;

int calc(const vector<pair<int, int> >& M, int idx_b, int idx_e,
         vector<vector<int> >& Memo) {
    if (idx_b == idx_e) return 0;
    if (Memo[idx_b][idx_e]) return Memo[idx_b][idx_e];
    int min = 2e9;
    for (int i = idx_b; i < idx_e; i++) {
        int val  = calc(M, idx_b, i, Memo) + calc(M, i + 1, idx_e, Memo)
                   + M[idx_b].first * M[i].second * M[idx_e].second;
        if (val < min) min = val;
    }
    return Memo[idx_b][idx_e] = min;
}

int main(){
    int n;
    cin >> n;
    vector<pair<int, int> > M;

    for (int i = 0; i < n; i++) {
        pair<int, int> input;
        cin >> input.first >> input.second;
        M.push_back(input);
    }
    vector<int> tmp(n, 0);
    vector<vector<int> > Memo(n, tmp);
    cout << calc(M, 0, M.size() - 1, Memo) << endl;

    return 0;
}

C++: #include <stdio.h>
#include <limits.h>
int main(){
  int n,p[101],i,j,k,l,x,m[101][101];
  scanf("%d",&n);
  for(i=1;i<=n;i++)scanf("%d %d",&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]=INT_MAX;
      for(k=i;k<j;k++){
	x=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
	if(m[i][j]>x)m[i][j]=x;
      }
    }
  }
  printf("%d\n",m[1][n]);
  return 0;
}

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

ll dp[101][101];

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

	}
	vector<ll> r(n),c(n);
	for(int i = 0;i<n;i++)cin >> r[i] >> c[i];

	for(int i =0;i<n-1;i++)
	{
		dp[i][i+2] = r[i] * c[i] * c[i+1];
	}
	for(int haba = 3;haba<=n;haba++)
	{
		for(int i = 0;i<=n-haba;i++)
		{
			for(int j = 1;j<haba;j++)
			{
				ll now = dp[i][i+j]+dp[i+j][i+haba]+r[i]*r[i+j]*c[i+haba-1];
				//if(i==0&&haba==4)
				//{
					//cout<<';'<<i<<' '<<i+j<<' '<<i+haba<<endl;
					//cout<<dp[i][i+j]<<' '<<dp[i+j][i+haba]<<';'<<r[i]<<' '<<r[i+j]<<' '<<c[i+haba-1]<<endl;
					//cout<<' '<<now<<endl;
				//}
				dp[i][i+haba] = min(dp[i][i+haba],now);
			}
		}
	}
	//for(int i = 0;i<n-1;i++){cout<<dp[i][i+2]<<endl;}
	//cout<<dp[1][4]<<endl;
	cout<<dp[0][n]<<endl;
}

C++: #include <stdio.h>
#include <iostream>
using namespace std;

class Matrix{
protected:
	int row;
	int col;
public:
	Matrix(int r, int c){ row = r; col = c; }
	int multiply(Matrix *mat);
	int multiply(Matrix *mat1, Matrix *mat3);
};

int Matrix::multiply(Matrix *mat)
{
	return row * col * mat->col;
}

int Matrix::multiply(Matrix *mat1, Matrix *mat3)
{
	return row * mat1->col * mat3->col;
}

class MatrixChain{
private:
	int len;
	Matrix **chain;
	int mult_num[100][100];
public:
	MatrixChain(int s);
	void addMatrix(Matrix *mat);
	int multiply(int i, int j);
};

MatrixChain::MatrixChain(int s)
{
	len = 0;
	chain = new Matrix*[s];
	for (int i = 0; i < 100; i++) {
		for (int j = 0; j < 100; j++) {
			mult_num[i][j] = 0;
		}
	}
}

void MatrixChain::addMatrix(Matrix *mat)
{
	chain[len] = mat;
	len++;
}

int MatrixChain::multiply(int i, int j)
{
	if (i >= j) return 0;

	if (mult_num[i][j] != 0) return mult_num[i][j];
	
	if (i + 1 == j) {
		mult_num[i][j] = chain[i]->multiply(chain[j]);
		return mult_num[i][j];
	}

	int mult_min;
	for (int k = i; k + 1 <= j; k++) {
		int temp = multiply(i, k) + multiply(k + 1, j);
		temp += chain[i]->multiply(chain[k], chain[j]);		
		if (k == i) mult_min = temp;
		else mult_min = min(temp, mult_min);
	}
	mult_num[i][j] = mult_min;
	return mult_num[i][j];
}

int main(void)
{
	int n;
	cin >> n;
	MatrixChain matc(n);
	for (int i = 0; i < n; i++) {
		int r, c;
		cin >> r >> c;
		matc.addMatrix(new Matrix(r, c));
	}

	cout << matc.multiply(0, n - 1) << endl;

	return 0;
}