Go: package main

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

type Matrix struct {
	r int // num of row
	c int // num of column
}

type Range struct {
	start int // index, inclusive
	end   int // index, inclusive
}

func calcMultiplication(x, y Matrix) (Matrix, int) {
	if x.c != y.r {
		panic("cannnot calculate")
	}
	return Matrix{x.r, y.c}, x.r * y.c * x.c
}

func calcMinMatrixChainMultiplication(matrices []Matrix, r Range, memo map[Range]int) (Matrix, int) {
	if v, ok := memo[r]; ok {
		return Matrix{matrices[0].r, matrices[len(matrices)-1].c}, v
	}
	if len(matrices) == 0 {
		panic("must not be empty")
	} else if len(matrices) == 1 {
		return matrices[0], 0
	} else if len(matrices) == 2 {
		return calcMultiplication(matrices[0], matrices[1])
	}

	var minCount int = math.MaxInt32

	for i := 0; i < len(matrices)-1; i++ {
		formerMatrices := matrices[:i+1]
		latterMatrices := matrices[i+1:]
		matF, countF := calcMinMatrixChainMultiplication(formerMatrices, Range{0, i}, memo)
		matL, countL := calcMinMatrixChainMultiplication(latterMatrices, Range{i + 1, len(matrices) - 1}, memo)
		_, countFL := calcMultiplication(matF, matL)
		count := countF + countL + countFL
		if count < minCount {
			minCount = count
		}
	}
	return Matrix{matrices[0].r, matrices[len(matrices)-1].c}, minCount
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	n, _ := nextInt(sc)
	matrices := make([]Matrix, n)
	for i := 0; i < n; i++ {
		r, _ := nextInt(sc)
		c, _ := nextInt(sc)
		matrices[i] = Matrix{r, c}
	}
	memo := make(map[Range]int)
	_, resultCount := calcMinMatrixChainMultiplication(matrices, Range{0, len(matrices) - 1}, memo)
	fmt.Println(resultCount)
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

Python: class Mychain:
    # 名前はこれでいいんだろうか・・・

    def __init__(self, n):
        self.n = n
        self.lst = [0 for _ in range(n * (n + 1) // 2)]

    def get_index(self, i, j):
        return i - 1 + ((j - i) * (2*self.n - j + i + 1) // 2)

    def get_value(self, i, j):
        return self.lst[self.get_index(i, j)]

    def set_value(self, i, j, value):
        index = self.get_index(i, j)
        self.lst[self.get_index(i, j)] = value


n = int(input())
res = Mychain(n)
matrix = [int(i) for i in input().split()]
matrix.extend([int(input().split()[1]) for i in range(n - 1)])


for n1 in range(1, n + 1):
    for i in range(1, n - n1 + 1):
        j = n1 + i
        value = min(res.get_value(i, i + k) + res.get_value(i + k + 1, j)
                    + matrix[i - 1] * matrix[i + k] * matrix[j]
                    for k in range(n1))
        res.set_value(i, j, value)

print(res.get_value(1, n))

Python: n = int(input())

p = [0 for i in range(n+1)]
for i in range(n):
    p[i],p[i+1] = map(int,input().split())
    
m = [[0 for i in range(n)] for j in range(n)]


for l in range(1,n):
    for i in range(0,n-l):
        j = i + l
        m[i][j] = float("inf")
        for k in range(i,j):
            m[i][j] = min(m[i][j],m[i][k] +m[k+1][j] + p[i]*p[k+1]*p[j+1])   
   
print(m[0][n-1])

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

m = [[0] * n for i in range(n)]

for l in range(2, n + 1):
    for i in range(n - k + 1):
        j = i + l - 1
        m[i][j] = float('inf')
        for k in range(i, j):
            m[i][j] = min(m[i][j], m[i][k] + m[k + 1][j] + p[i][0] * p[k][1] * p[j][1])

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

Python: import sys
import math
import string
import fractions
import random
from operator import itemgetter
import itertools
from collections import deque
import copy
import heapq
from bisect import bisect, bisect_left, bisect_right

MOD = 10 ** 9 + 7
INF = float('inf')
input = lambda: sys.stdin.readline().strip()

sys.setrecursionlimit(10 ** 8)

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

dp = [[INF] * (n + 10) for _ in range(n + 10)]

"""
dp[i][j] = iからj番目の行列積に必要なスカラー積の最小値
dp[i][j] = min(dp[i][k] + dp[k+1][j] + M[i].row * M[k].col * M[j].col)
"""

for i in range(n):  # 初期条件
    dp[i][i] = 0

for i in range(n, -1, -1):
    for j in range(i+1, n):
        for k in range(i, j):
            prod = row[i] * column[k] * column[j]
            dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + prod)
print(dp[0][n-1])

Python: """
n = input().split()

n = input()
nele = int(n[0])
list = range(1,nele+1)

nrow = {}
ncol = {}
for i in list:
	nrow[i] = int(n[i*2-1])
	ncol[i] = int(n[i*2])
"""

n = input()
nele = int(n[0])
list = range(1,nele+1)
nrow = {}
ncol = {}
for i in list:
	n = input().split()
	nrow[i] = int(n[0])
	ncol[i] = int(n[1])


#print(nrow, ncol)


min = -1
cur = -1
route = []
done = []

for i in list:
	route.append(0)

#print(route)

depth = -1
min = -1
def tansaku(prev):
	
	global depth
	depth += 1
	
	global nrow
	global ncol
	global min
	global route
	
	done = route[:]
	
	for i in list:
#		print(depth, i, route, done)
		
		if i in done:
			continue
		
		next = i
		done.append(next)
		
		if depth == 0:
			route[depth] = next
			tmp = 0
			min = tansaku(tmp)
			continue
		
		tmp = prev + nrow[route[depth-1]] * ncol[next]
#		print(tmp)
		
		if tmp > min and min != -1:
#			print("aaa")
			continue
		else:
			route[depth] = next
			if depth >= nele-1:
#				print("bbb")
				min = tmp
			else:
#				print("ccc")
				min = tansaku(tmp)
	
	depth -= 1
	route[depth] = 0
#	print("min:", min)
	return min

min = tansaku(0)

print(min)

Python: n = int(input())
INF = 10**9
P = []
for i in range(n):
    p = map(int, input().split())
    P.append()
m = [[0]*n for i in range(n)]

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

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

Python: def matrixChainMultiplication():
    for i in range(1, n+1):
        m[i][i] = 0

    for l in range(2, n+1):
        for i in range(1, n-l+2):
            j = i + l - 1
            m[i][j] = INF
            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])
    return m[1][n]

if __name__ == "__main__":
    INF = 10000000000000
    p = []
    n = int(input())
    m = [[None] * (n+1) for i in range(n+1)]
    for i in range(n):
        inp = list(map(int, input().split()))
        if i == 0:
            p.append(inp[0])
            p.append(inp[1])
        else:
            p.append(inp[1])
    print(matrixChainMultiplication())

Python: n = int(input())
P = []
for i in range(n):
    p = map(int, input().split())
    P.append()
m = [[0]*n for i in range(n)]

for l in range(2, n + 1):
    for i in range(n - l + 1):
        j = i + l - 1
        m[i][j] = float("inf")
        for k in range(i, j):
            m[i][j] = min(m[i][j], m[i][k] + m[k + 1][j] + p[i - 1][0] * p[k][1] * p[j][1])

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

Python: #coding:UTF-8
def chain(p,n):
    m={}
    for i in range(1,n+1):
        m[i] = {i:0}
         
    for l in range(2,n+1):
        for i in range(1,n-l+2):
            j = i + l -1
            m[i][j] = float("inf")
            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])
    
if __name__=="__main__": 
    p={}
    n = int(input())
    for i in range(1,n+1):
        st = input()
        w = st.split()
        p[i-1] = int(w[0])
        p[i]   = int(w[1])
    chain(p,n)