Go: package main

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

var cache [100][100]int

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Scan()
	num, _ := strconv.Atoi(sc.Text())
	tables := []table{}
	for i := 0; i < num; i++ {
		sc.Scan()
		num1, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		num2, _ := strconv.Atoi(sc.Text())
		t := table{num1, num2}
		tables = append(tables, t)
	}

	fmt.Println(minimum(0, len(tables)-1, tables))
}

type table struct {
	v int
	h int
}

func minimum(i int, j int, t []table) int {
	if i == j {
		return 0
	}

	// fmt.Printf("i:%v j:%v\n", i, j)
	if cache[i][j] != 0 {
		return cache[i][j]
	}

	min := math.MaxInt64
	for k := i; k < j; k++ {
		p := t[i].v
		n := t[k].h
		q := t[j].h
		val := minimum(i, k, t) + minimum(k+1, j, t) + p*n*q
		if val < min {
			min = val
		}
	}

	cache[i][j] = min
	return min
}

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

#define MAX 1000
#define INFINITY 2000000000

int A[MAX];
int m[MAX][MAX];
int n;

void minimumCount() {
    for (int i = 0; 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] = INFINITY;
            for (int k = i; k < j; ++k) {
                m[i][j] = std::min(m[i][j], m[i][k] + m[k+1][j] + A[i-1] * A[k] * A[j]);
            }
        }
    }
}

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

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] = (l<<21);
            for(int 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 <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0; i<(n); i++)
#define FOR(i,x,n) for(int i=x; i<(n); i++)
#define ALL(n) begin(n),end(n)
#define MOD (1000000007)
#define INF (1e9)
#define INFL (1e18)
 
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
template<class T>using arr=vector<vector<T>>;
template<class T>void pr(T x){cout << x << endl;}
template<class T>void prvec(vector<T>& a){rep(i, a.size()-1){cout << a[i] << " ";} cout << a[a.size()-1] << endl;}
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
template<class T>void prarr(vector<vector<T>>& a){
rep(i, a.size()){
rep(j, a[i].size()){
cout << a[i][j]; printf(" ");}
printf("\n");} printf("\n");}

vector<ll> row, col;
arr<ll> dp;
ll ans = INFL;
int n; 

ll dfs(int l, int r){
    // printf("%lld %lld\n", l, r);
    if(dp[l][r]!=INFL) return dp[l][r];
    if(l==r) return dp[l][r] = 0;
    if(r==l+1) return dp[l][r] = row[l] * col[l] * col[r];

    ll tmp = INFL;
    FOR(k, l, r){
        chmin(tmp, dfs(l, k) + dfs(k+1, r) + row[l] * col[k] * col[r]);
    }

    return dp[l][r] = tmp;
}

int main()
{
    cin >> n;
    row.resize(n); col.resize(n);
    rep(i, n){
        cin >> row[i] >> col[i];
    }
    dp.assign(n, vector<ll>(n, INFL));

    ans = dfs(0, n-1);
    
    // prarr(dp);
    pr(ans);
    return 0;}

C++: #include <iostream>
#include <array>
#include <limits>

using namespace std;

struct MatrixDims {
    int row;
    int col;
    MatrixDims() {}
    MatrixDims(int row, int col) : row(row), col(col) {}
};

array<MatrixDims, 100> matrix_dims;
array<array<int, 100>, 100> dp;

int get_min(int row, int col) {
    int min = numeric_limits<int>::max();
    for (int j = row; j < col; ++j) {
        int sum = dp[row][j] + dp[j+1][col] + matrix_dims[row].row * matrix_dims[j].col * matrix_dims[col].col;
        if (sum < min) min = sum;
    }
    return min;
}

int main()
{
    int n;
    cin >>  n;
    for (int i = 0; i < n; ++i) {
        int row, col;
        cin >> row >> col;
        matrix_dims[i] = MatrixDims(row, col);
    }
    dp.fill({});
    
    for (int endpt = 1; endpt < n; ++endpt) {
        for (int diag_i = 0; (endpt + diag_i) < n; ++diag_i) {
            dp[diag_i][diag_i + endpt] = get_min(diag_i, endpt + diag_i);
        }
    }
    cout << dp[0][n-1] << endl;
}

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

static const long N = 100;

int main(){
	long n, p[N + 1], m[N + 1][N + 1];
	cin >> n;
	for (long i = 1; i <= n; i++){
		cin >> p[i - 1] >> p[i];
	}

	for (long i = 1; i <= n; i++) m[i][i] = 0;
	for (long l = 2; l <= n; l++){
		for (long i = 1; i <= n - l + 1; i++){
			long j = i + l - 1;
			m[i][j] = (1 << 21);
			for (long 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<map>
#include<array>

using lr = std::pair<int, int>;
using lr_map = std::map<lr, int>;

int rc(int mat[], lr_map &dp, int n, int rest_n, int limit);

int main()
{
	int n, mat[101]{}, count{};
	lr_map dp;

	scanf("%d%d%d", &n, mat, mat + 1);
	for (int i = 1; i < n; ++i)
		scanf("%d%d", mat + i, mat + i + 1);

	printf("%d\n", rc(mat, dp, 0, n, 2000000000));

	return 0;
}

int rc(int mat[], lr_map &dp, int left, int right, int min)
{
	if (left + 1 == right) return 0;
	if (dp.find(lr{ left, right }) != dp.end()) return dp[lr{ left, right }];

	for (int mid = left + 1; mid < right; ++mid)
	{
		int tmp = mat[left] * mat[mid] * mat[right];
		tmp += rc(mat, dp, left, mid, min);
		if (tmp > min) continue;

		tmp += rc(mat, dp, mid, right, min);
		if (tmp > min) continue;

		min = tmp;
	}
	dp[lr{ left, right }] = min;
	return min;
}

C++: 4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 
#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 - 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 <cstdio>
#include <algorithm>
using namespace std;
int m[107], dp[107][107];
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
    	scanf("%d%d", &m[i], &m[i + 1]);
	}
	for (int l = 2; l <= n; l++) {
		for (int i = 1; i <= n - l + 1; i++) {
			int j = i + l - 1;
			dp[i][j] = 1e9 + 7;
			for (int k = i; k < j; k++) {
				dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + m[i - 1] * m[k] * m[j]);
			}
		}
	}
	printf("%d\n", dp[1][n]);
    return 0;
}

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

int main(){
	int n, p[101],m[101][101];
	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;
	
}