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++: // includes
#include <bits/stdc++.h>
using namespace std;

// macros
#define pb emplace_back
#define mk make_pair
#define FOR(i, a, b) for(int i=(a);i<(b);++i)
#define rep(i, n) FOR(i, 0, n)
#define rrep(i, n) for(int i=((int)(n)-1);i>=0;i--)
#define irep(itr, st) for(auto itr = (st).begin(); itr != (st).end(); ++itr)
#define irrep(itr, st) for(auto itr = (st).rbegin(); itr != (st).rend(); ++itr)
#define whole(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bit(n) (1LL<<(n))
// functions
template <typename T> void unique(T& c){c.erase(std::unique(c.begin(), c.end()), c.end());}
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(a > b){a = b; return 1;} return 0;}
template <typename T> istream &operator>>(istream &is, vector<T> &vec){for(auto &v: vec)is >> v; return is;}
template <typename T> ostream &operator<<(ostream &os, const vector<T>& vec){for(int i = 0; i < vec.size(); i++){ os << vec[i]; if(i + 1 != vec.size())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T>& st){for(auto itr = st.begin(); itr != st.end(); ++itr){ os << *itr; auto titr = itr; if(++titr != st.end())os << " ";} return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &p){os << "(" << p.first << ", " << p.second << ")"; return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << "(" << itr->first << ", " << itr->second << ")"; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
template <typename T1, typename T2> ostream &operator<<(ostream &os, const unordered_map<T1, T2> &mp){for(auto itr = mp.begin(); itr != mp.end(); ++itr){ os << "(" << itr->first << ", " << itr->second << ")"; auto titr = itr; if(++titr != mp.end())os << " "; } return os;}
//  types
using ll = long long int;
using P = pair<int, int>;
// constants
const int inf = 1e9;
const ll linf = 1LL << 50;
const double EPS = 1e-10;
const int mod = 1000000007;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};
// io
struct fast_io{
  fast_io(){ios_base::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(20);}
} fast_io_;

int R[110], C[110];
ll memo[110][110];

ll calc(int l, int r){
  if(memo[l][r] > 0)return memo[l][r];
  if(r == l + 1)return 0;
  ll res = linf;
  for(int k = l; k < r - 1; k++){
    chmin(res, calc(l, k+1) + calc(k+1, r) + R[l] * C[k] * C[r-1]);
  }
  return memo[l][r] = res;
}

int main(int argc, char const* argv[])
{
  int n; cin >> n;
  rep(i, n)cin >> R[i] >> C[i];
  cout << calc(0, n) << endl;
  return 0;
}

C++: #define PI 3.14159265359
#define INF 2000000000
#define MAX 500000
#include <map>
#include <algorithm>
#include <vector>
#include <queue>
#include <iostream>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
using namespace std;
typedef long long ll;


void MCM(int n,int p[]){
  int m[120][120];
  for(int i=1;i<=n;i++) for(int j=0;j<=n;j++) m[i][j]=(1<<30);
  
  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-1+l;
          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;
}

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

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

using namespace std;

int main(){
    int n;
    cin >> n;

    pair<int, int> p[n];
    for(int i=0; i<n; i++){
        int t1, t2;
        cin >> t1 >> t2;
        p[i] = make_pair(t1, t2);
    }

    int dp[n][n];
    for(int i=0; i<n; i++){
        for(int j=0; j<n; j++){
            dp[i][j] = 1000000000;
            if(i==j) dp[i][j] = 0;
        }
    }

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

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

    return 0;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;
#define INF (99999999)
int main(){

  //-------データの入力------------
  int n;
  cin >> n;
  int row[n];
  int column[n];
  for(int i = 0; i < n; i++){
    cin >> row[i] >> column[i];
  }
  //-----------------------------

  //[始点][終点（始点+幅）]の最小コスト
  int dp[n][n];

  //INFで初期化
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      dp[i][j] = INF;
    }
  }

  //幅0はコスト0
  //dp[i][i+0] = 0
  for(int i = 0; i < n; i++){
    dp[i][i] = 0;
  }

  //幅:j = 0 から n-1 まで
  for(int j = 0; j < n; j++){
    //始点: i から n -j まで
    for(int i = 0; i < n - j; i++){
      //仕切りを置く位置: k
      // (M_0, M_1, M_2, M_3) | (M_4, M_5)
      for(int k = i + 1; k <= i + j; k++){
        //現在のdp[i][i+j]より小さければ更新
        dp[i][i+j] = min(dp[i][i+j], dp[i][k-1] + dp[k][i+j] + row[i] * column[k-1] * column[i+j]);
      }
    }
  }
  /*
  for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
      cout << dp[i][j] << " ";
    }
    cout << endl;
  }
  */
  //始点０、幅n-1の最小コスト=> n個の行列の連鎖の計算に最低限必要な乗算の回数　を出力
  cout << dp[0][n-1] << endl;
  return 0;
}

C++: #include <bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
#define int long long
using namespace std;
int dp[111][111],n,L[111],R[111];

int dfs(int l,int r){
	if(dp[l][r]!=-1)return dp[l][r];
	if(l==r)return 0;
	int res=1e17;
	for(int i=l;i<r;i++){
		res=min(res,dfs(l,i)+dfs(i+1,r)+L[l]*R[i]*R[r]);
	}
	return dp[l][r]=res;
}

signed main(){
	memset(dp,-1,sizeof(dp));
	cin>>n;
	r(i,n)cin>>L[i]>>R[i];
	dfs(0,n-1);
	cout<<dp[0][n-1]<<endl;
}