Go: package main

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

//util
var sc = bufio.NewScanner(os.Stdin)

func nextStr() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func printList(list []int) {
	buf := bufio.NewWriter(os.Stdout)
	for _, v := range list {
		buf.Write([]byte(fmt.Sprintf(" %d", v)))
	}
	buf.Write([]byte("\n"))
	buf.Flush()
}

//solve
//単純な場合
func matrixChainMultiplication() {
	//行列が1つだけのとき
	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
			//kまでで区切る
			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])
			}
		}
	}
}

func max(a, b int) int {
	if a > b {
		return a
	} else {
		return b
	}
}

func min(a, b int) int {
	if a > b {
		return b
	} else {
		return a
	}
}

const MAX = 100

var n int
var p [MAX + 1]int

//m[i][j]: Mi * Mi+1 * ... * Mjを計算するときに必要なスカラー乗算の最小回数
var m [MAX + 1][MAX + 1]int

func main() {
	sc.Split(bufio.ScanWords)
	n = nextInt()
	for i := 1; i <= n; i++ {

		p[i-1] = nextInt() //行数
		p[i] = nextInt()   //列数
	}

	matrixChainMultiplication()
	fmt.Println(m[1][n])
}

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

int main() {
  int n;
  cin >> n;
  
  vector<int> p(n + 1);
  for (int i = 0; i < n; i++) {
    cin >> p.at(i) >> p.at(i + 1);
  }
  
  vector<vector<int> > m(n + 1, vector<int> (n + 1));
  
  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;
}

C++: #include <bits/stdc++.h>
//----***やべーやつら***----
using namespace std;
#define int long long

//----***型定義***----
using ll = long long;
using P = pair<int,int>;

//----***Like a Pythonista***----
#define REP(ii,jj,nn) for (ll ii=jj;ii<(nn);ii++)
#define RREP(ii,nn,jj) for (ll ii = nn; jj<ii;ii--)
#define each(i,...) for (auto&& i:__VA_ARGS__)
#define ALL(vec) (vec).begin(),(vec).end()
#define sum(...) accumulate(ALL(__VA_ARGS__),0LL)
#define dsum(...) accumulate(ALL(__VA_ARGS__),0.0)
#define vec(type,name,...) vector<type> name(__VA_ARGS__)
template<class T> inline auto max(const T& a){ return *max_element(ALL(a)); }
template<class T> inline auto min(const T& a){ return *min_element(ALL(a)); }
inline ll gcd(ll a,ll b){if(b == 0) return a;return  gcd(b,a%b);}
inline ll lcm(ll a,ll b){ll g = gcd(a,b);return a / g * b;}

//----***定数***----
#define MOD 1000000007
#define INF 100000000000000000
#define EPS 1e-9
const vector<vector<int>> DXY={{-1,0},{1,0},{0,-1},{0,1}};

//----***パーツ***----
#define fr first
#define se second
#define pb push_back

//----***入出力***---
#define print(out) cout<< out  << "\n";
#define debug(var)  do{std::cerr << #var << " ↓ "<<"\n";view(var);}while(0);
#define dbg cerr<<"🥺🥺🥺🥺🥺🥺"<<endl;
template<typename T> void view(T e){std::cout << e << std::endl;}
template<typename T> void view(const std::vector<T>& v){for(const auto& e : v){ std::cout << e << " "; } std::cout << std::endl;}
template<typename T> void view(const std::vector<std::vector<T> >& vv){ for(const auto& v : vv){ view(v); } }

//----***初期時読み込み***----
struct initial{initial(){cin.tie(0); ios::sync_with_stdio(0); cout<<fixed<<setprecision(15);};}initial_;

vector<vector<int>>dp(30,vector<int>(500,0));

signed main(){
  int N;cin>>N;
  vector<P> M(N);
  REP(i,0,N)cin>>M[i].fr>>M[i].se;
  vector<vector<int>> dp(N+1,vector<int>(N+1,INF));
  REP(i,0,N+1)dp[i][i]=0;

  REP(w,1,N)REP(i,0,N-w){
    int j=i+w;
    REP(k,i,j){
        int prod=M[i].fr*M[k].se*M[j].se;
        dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+prod);
    }
  }
  print(dp[0][N-1])
}

C++: #include<stdio.h>

int matrixChainOrder(int *p);
int m[101][101];
int n1;
int main(){
  
  int i,r,c,min;
  int p[100];
  scanf("%d",&n1);

  for(i=0;i<n1;i++){
    scanf("%d %d",&r,&c);
    if(i==n1-1) p[n1]=c;
    p[i]=r;
  }

  min = matrixChainOrder(p);
  printf("%d\n",min);

  return 0;
}

int matrixChainOrder(int *p){
  int n2,l,i,j,q,k;
  
  n2 = n1 - 1;
  for(i=1;i<=n2;i++){
    m[i][i] = 0;
  }
  for(l=2;l<=n2;l++){ 
    for(i=1;i<=n2-l+1;i++){ 
      j = i+l-1;
      m[i][j] = 1.0/0.0;
      for(k=i;k<j;k++){
	q = m[i][k] + m[k+1][j]+p[i-1]*p[k]*p[j];
        if(m[i][j]>=q)  m[i][j] = q;
      }
    }
  }
  return m[i][j];
}

C++: #include <iostream>
#include <algorithm>
#include <vector>
#include <math.h>
#include <cmath>
#include <string>
#include <cstdio>
using namespace std;
typedef long long int ll;
static int const 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 i = 2; i <= n; i++) {
		for (int j = 1; j <= n - i + 1; j++) {
			int k = j + i - 1;
			M[j][k] = (1 << 21);
			for (int l = j; l <= k - 1; l++) {
				M[j][k] = min(M[j][k], M[j][l] + M[l+1][k] + P[j - 1] * P[l] * P[k]);
			}
		}
	}
	cout << M[1][n] << endl;
}

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

static const int N = 100;

int main() {
	int n;
	int 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 = 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] = (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 <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rrep(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) int(x.size())
#define get_unique(x) x.erase(unique(all(x)), x.end());
typedef long long ll;
typedef complex<double> Complex;
const int INF = 1e9;
const ll MOD = 1e9 + 7;
const ll LINF = 1e18;
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>
vector<T> make_vec(size_t a) {
    return vector<T>(a);
}
template <class T, class... Ts>
auto make_vec(size_t a, Ts... ts) {
    return vector<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}
int n;
vector<ll> r, c;
auto memo = make_vec<ll>(110, 110);
ll dp(int i, int j) {
    if (memo[i][j] != -1) return memo[i][j];
    if (i == j) return memo[i][j] = 0;
    ll ret = LINF;
    for (int k = i; k < j; k++) {
        chmin(ret, dp(i, k) + dp(k + 1, j) + r[i] * c[k] * c[j]);
    }
    return memo[i][j] = ret;
}
int main() {
    cin >> n;
    r.resize(n);
    c.resize(n);
    rep(i, n) cin >> r[i] >> c[i];
    rep(i, 110) rep(j, 110) memo[i][j] = -1;
    cout << dp(0, n - 1) << endl;
}

C++: #include<bits/stdc++.h>
using namespace std;
#define chmax(a,b) a=max(a,b)
#define chmin(a,b) a=min(a,b)
#define INF 100100100100100

int main(){

    long long n; cin >> n;
    vector<long long> r(n);
    vector<long long> c(n);
    for(long long i = 0; i < n; i++){
        cin >> r[i] >> c[i];
    }

    vector<vector<long long> > dp(n + 1, vector<long long> (n + 1, INF));
    for(int i = 0; i < n; i++) dp[i][i + 1] = 0;
    
    for(int k = 2; k <= n; k++){
        for(int i = 0; i < n; i++){
            for(int j = 1; j < k; j++){
                if(i + k <= n){
                    chmin(dp[i][i + k], dp[i][i + j] + dp[i + j][i + k] + r[i] * c[i + j - 1] * c[i + k - 1]);
                }
            }
        }
    }

    cout << dp[0][n] << endl;
    
    return 0;
}