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])
}

Python: def main():
    from functools import lru_cache
    import sys
    input=sys.stdin.readline
    sys.setrecursionlimit(100000000)
    INF=10**9
    n=int(input())
    M=[list(map(int,input().split())) for _ in range(n)]
   
    @lru_cache(maxsize=None)
    def dp(i,j):
        if i+1==j:
            return 0
        else:
            ans=INF
            for k in range(i+1,j):
                ans=min(ans,dp(i,k)+dp(k,j)+M[i][0]*M[k][0]*M[j-1][1])
            return ans
    print(dp(0,n))

if __name__=='__main__':
    main()

Python: # -*- coding: utf-8 -*-
"""
Created on Fri Mar 22 14:15:50 2019

@author: Yamazaki Kenichi
"""

n = int(input())
A = [list(map(int,input().split())) for i in range(n)]
B = [A[0][0]]
for c in A:
    B += [c[1]]

T = [[0 for i in range(n)] for i in range(n)]
for i in range(1,n):
    for j in range(n-i):
        if i == 1:
            T[i][j] = B[j]*B[j+1]*B[j+2]
            continue
        temp = 10**6
        for k in range(1,i+1):
             temp = min(temp,
                        T[i-k][j] + T[k-1][j+(i-k)+1] + B[j]*B[j+i-k+1]*B[j+i+1])
        T[i][j] = temp
print(T[n-1][0])

Python: if'__main__'==__name__:s()
def s():
 n=int(input())+1
 e=[input().split()for _  in[0]*~-n]
 p=[int(e[0][0])]+list(int(x[1])for x in e)
 m=[[0]*n for _ in[0]*n]
 for l in range(2,n):
  for i in range(1,n-l+1):
   j=i+l-1;m[i][j]=1e6
   for k in range(i,j):m[i][j]=min(m[i][j],m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j])
 print(m[1][n-1])

Python: n = int(input())
P = list(map(int,input().split()))
for _ in range(n-1):
    P.append(int(input().split()[1]))

INF = 10**18
dp = [[INF]*(n) for i in range(n)]

for i in range(n):#一つの行列部分にゼロを入れる
    dp[i][i] = 0

for l in range(1,n):
    for i in range(n-l):
        j = i + l
        dp[i][j] = INF
        for k in range(i,j):
            dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + P[i-1] * P[k] * P[j])

print(dp[0][n-1])

Python: n = int(input())
rc = [[0, 0]]+[list(map(int, input().split())) for i in range(n)]
m = [[0]*(n+1) for _ in range(n+1)]

for l in range(2, n+1):
    for i in range(1, n-l+2):
        j = i+l-1
        m[i][j] = 2**64
        for k in range(i, j):
            m[i][j] = min([
                m[i][j],
                m[i][k]+m[k+1][j]+rc[i][0]*rc[k+1][0]*rc[j][1]
            ])
print(m[1][n])

Python: def memoize(f):  
    cache = {}  
    def helper(x):  
        if x not in cache:              
            cache[x] = f(x)  
        return cache[x]  
    return helper 

def split_rc(rc):
    for i in range(1, len(rc)):
        yield rc[:i], rc[i:]

@memoize
def cost(rc):
    if len(rc) == 1:
        return 0
    return min(calc_cost(first, second) for first, second in split_rc(rc))

def calc_cost(first, second):
    return cost(first) + cost(second) + first[0][0] * first[-1][1] * second[-1][1]

n = int(input())
rc = tuple(tuple(map(int, input().split())) for _ in range(n))
print(cost(rc))

Python: n = int(input())
data = []
for i in range(n):
    data.append(list(map(int, input().split())))

memo = []
for _ in range(n):
    memo.append([-1]*n)


def mul(i, j):
    if i == j:
        return 0
    if memo[i][j] >= 0:
        return memo[i][j]
    num = 100000
    for k in range(i, j):
        num = min(num, mul(i, k) + mul(k+1, j) + data[i][0] * data[k][1] * data[j][1])
    memo[i][j] = num
    return memo[i][j]

print(mul(0, n-1))

Python: import sys, copy

num = int(sys.stdin.readline())

if num==1:
    print(0)
    quit()
    
mm = list(map(int, sys.stdin.readline().split()))
for _ in range(num-1):
    mm.append(int(sys.stdin.readline().split()[1]))

used = [False] * num
seq = [0] * (num-2)
minv = 0
j=mm[1]
for i in mm[2:]:
    minv += i*j
    j=i
minv *= mm[0]    

print('min=',minv)
def sequence(n, k, m, t):
    global minv, used, seq
    if k==m:
        t += mm[0]*mm[used[1:].index(False)+1]*mm[num]
        if minv>t:    minv = t
    else:
        for i in range(1,n+1):
            if used[i]: continue
            seq[m] = i
            used[i]=True

            l=i-1
            while l>0 and used[l]:     l-=1
            u=i+1
            while u<num and used[u]:   u+=1
            v = mm[l]*mm[i]*mm[u]
            if minv>t+v: sequence(n, k, m+1, t+v)
            used[i]=False

sequence(num-1, num-2, 0, 0)

print(minv)

Python: #!/usr/bin/env python3
# -*- coding: utf-8 -*-

import sys
import re
import math
import collections
import itertools
import functools
import logging

logging.basicConfig(level=logging.DEBUG, format="DBG: %(message)s")

def dbg(msg, *args, **kwargs):
    logging.debug(msg, *args, **kwargs)

Mat = collections.namedtuple("Mat", "r c")

def mat_mul(ms):
    return Mat(ms[0].r, ms[-1].c)

def cost(m1, m2):
    return m1.r * m1.c * m2.c

def solve(n, ms):
    if n == 1: return 0

    dp = {}
    for i in range(n):
        dp[(i,i)] = 0

    for l in range(2, n+1):
        for i in range(n-l+1):
            #cost_min = math.inf
            cost_min = float("inf")
            for j in range(l-1):
                #dbg("l, i, j: %d %d %d", l, i, j)
                m_lhs = mat_mul(ms[i:i+j+1])
                m_rhs = mat_mul(ms[i+j+1:i+l])
                #dbg("m_lhs, m_rhs: %r %r", m_lhs, m_rhs)
                cost_lhs = dp[(i,i+j)]
                cost_rhs = dp[(i+j+1,i+l-1)]
                #dbg("cost_lhs, cost_rhs: %d %d", cost_lhs, cost_rhs)
                cost_mul = cost(m_lhs, m_rhs)
                #dbg("cost_mul: %d", cost_mul)
                cost_now = cost_mul + cost_lhs + cost_rhs
                #dbg("cost_now: %d", cost_now)
                if cost_min > cost_now:
                    cost_min = cost_now
            dp[(i,i+l-1)] = cost_min

    #dbg(dp)
    return dp[(0,n-1)]

def main():
    n = int(input())

    ms = []
    for _ in range(n):
        r,c = map(int, input().split())
        ms.append(Mat(r,c))

    print(solve(n, ms))

if __name__ == "__main__": main()

Python: n = int(input())
r=[0]*(n+1)
c=[0]*(n+1)
for i in range(n):
    r[i+1], c[i+1] = map(int, input().split())

dp = [[float('inf') for i in range(n+1)] for j in range(n+1)]

for i in range(n+1):
    dp[i][i] = 0

# print("")
for l in range(2, n+1):
    for i in range(1, n-l+2):
        # print("l=", l, "i=", i)
        tmp_list = [r[i] * c[i+l-1] * r[j+1] + dp[i][j] + dp[j+1][i+l-1] for j in range(i, i+l-1)]
        dp[i][i+l-1] = min(tmp_list)

print(dp[1][n])

Python: n=int(input())+1
e=[input().split()for _  in[0]*~-n]
p=[int(e[0][0])]+list(int(x[1])for x in e)
m=[[0]*n for _ in[0]*n]
for l in range(2,n):
 for i in range(1,n-l+1):
  j=i+l-1;m[i][j]=1e6
  for k in range(i,j):m[i][j]=min(m[i][j],m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j])
print(m[1][n-1])