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 (r Range) length() int {
	return r.end - r.start + 1
}

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[r.start].r, matrices[r.end].c}, v
	}
	if r.length() == 0 {
		panic("must not be empty")
	} else if r.length() == 1 {
		return matrices[r.start], 0
	}

	var minCount int = math.MaxInt32

	for i := 0; i < r.length()-1; i++ {
		formerRange := Range{r.start, r.start + i}
		latterRange := Range{r.start + i + 1, r.end}
		matF, countF := calcMinMatrixChainMultiplication(matrices, formerRange, memo)
		matL, countL := calcMinMatrixChainMultiplication(matrices, latterRange, memo)
		_, countFL := calcMultiplication(matF, matL)
		count := countF + countL + countFL
		if count < minCount {
			minCount = count
		}
	}
	memo[r] = minCount
	return Matrix{matrices[r.start].r, matrices[r.end].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: N = int(input())

for i in range(N):
    if i == 0:
        P = list(map(int, input().split()))  # Pは各行列の次元
        continue
    P.append(int(input().split()[1]))

# dpテーブルの用意 minを取るときはinf埋めしておくと処理が楽になるしバグが見つかりやすい
#dp[i][j]は(Mi...Mj)のminコストを入れる
INF = 2**32-1
dp = [[INF]*N for _ in range(N)]

#dpテーブルの対角成分を0で初期化
#dp[s][s]はMsのminコストを表す（Msは単独の行列）
for ij in range(N):
    dp[ij][ij] = 0

# 最終的に求めたいのはdp[0][N]だが、計算途中で繰り返すそれぞれの行列積をdpに入れておくことで効率化
for l in range(1, N):  # l は対象とする行列の個数を表す
    for i in range(N):
        j = i+l   # Mj はMiから何個の行列を考えるかで決まる
        if j >= N:  # 計算するのはインデックスはN-1まで
            continue
        for k in range(i, j):  # (Mi...Mk)(Mk+1...Mj) のようにどこでMkで区切るかを動かす
            dp[i][j] = min(dp[i][k] + dp[k+1][j] + P[i] * P[j+1]*P[k+1], dp[i][j]) # 
print(dp[0][-1])

Python: import sys

p=[0 for i in range (101)]
m=[[0 for i in range(100)]for i in range(100)]

def MatrixChain(n) : 
	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('Infinity')
			for k in range(i,j) :
				q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
				m[i][j] = m[i][j] if m[i][j] <= q else q

n = int(input())
for i in range(n) :
	input_num = input()
	input_num = input_num.split(' ')
	p[i] = int(input_num[0][0])
	p[i+1] = int(input_num[1])

MatrixChain(n)
print(m[1][n])

Python: import sys


def getmin(i, j, mlist, memo={}):
    if i == j:
        return 0
    elif (i, j) in memo:
        return memo[(i, j)]
    else:
        ret = sys.maxsize
        for k in range(i, j):
            p = mlist[i][0]
            n = mlist[k][1]
            q = mlist[j][1]
            tmp = getmin(i, k, mlist, memo) + \
                getmin(k+1, j, mlist, memo) + p*n*q

            if tmp < ret:
                ret = tmp

        memo[(i, j)] = ret
        return memo[(i, j)]


def main():
    n = int(input())
    M = [[0, 0] for i in range(n)]
    for i in range(n):
        M[i] = list(map(int, input().split()))

    print(getmin(0, n-1, M))


if __name__ == '__main__':
    main()

Python: N=int(input())

input_=[N]
for n in range(N):
    input_.append(input())
    
P=[]
for n in range(N):
    P.append(int(input_[n+1].split()[0]))
    
P.append(int(input_[n+1].split()[1]))

M=[[0]*(N) for x in range(N)]

for n in range(1,N):
    for i in range(N-n):
        M[i][i+n]=10**100
        for k in range(i,i+n):
            P_0=P[i]
            P_1=P[k+1]
            P_2=P[i+n+1]
            M_=M[i][k]+M[k+1][i+n]+P_0*P_1*P_2
            M[i][i+n]=min(M[i][i+n],M_)
            
print(M[0][-1])

Python: N = int(input())

for i in range(N):
    if i == 0:
        P = list(map(int, input().split()))
        continue
    P.append(int(input().split()[1]))

INF = 2 ** 32 - 1
dp = [[INF] * N for _ in range(N)]

for ij in range(N):
    dp[ij][ij] = 0

for l in range(1, N):
    for i in range(N):
        j = i + l
        if j >= N:
            continue
        for k in range(i, j):
            dp[i][j] = min(dp[i][k] + dp[k+1][j] + P[i] * P[j+1]*P[k+1],
                           dp[i][j])

print(dp[0][-1])

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

import sys


def mat_mul_opt(_mat_info):
    rc_info.extend(list(map(int, _mat_info[0])))
    rc_info.extend(list(map(lambda x: int(x[1]), _mat_info[1:])))

    for l in range(2, mat_num + 1):
        for i in range(1, mat_num - l + 2):
            j = i + l - 1
            ans[i][j] = 1e7
            for k in range(i, j):
                ans[i][j] = min(ans[i][j], ans[i][k] + ans[k + 1][j] +
                                rc_info[i - 1] * rc_info[k] * rc_info[j])

    return ans[1][mat_num]


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    mat_num = int(_input[0])
    mat_info = tuple(map(lambda x: x.split(), _input[1:]))

    rc_info = []
    ans = [[0] * (mat_num + 1) for _ in range(mat_num + 1)]
    print(mat_mul_opt(mat_info))

Python: def main():
    """ MAIN """
    DAT = []
    num = int(input())
    for i in range(num):
        x, y = list(map(int,input().split()))
        DAT.append(x)
    DAT.append(y)
    num1 = num + 1
    TBL = [[0] * num1 for i in range(num1)]

    for i in range(0, num1):
        for row in range(num-i):
            col = row + i + 1
            for j in range(row+1,col):
                x = DAT[row] * DAT[j] * DAT[col] + TBL[row][j] + TBL[j][col]
                if TBL[row][col] < 1 or TBL[row][col] > x:
                    TBL[row][col] = x

    print("{}".format(TBL[row][col]))

if __name__ == '__main__':
    main()

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

import sys


def mat_mul_opt(_mat_info):
    rc_info = list(map(int, _mat_info[0]))
    rc_info.extend(list(map(lambda x: int(x[1]), _mat_info[1:])))

    for l in range(2, mat_num + 1):
        for i in range(1, mat_num - l + 2):
            j = i + l - 1
            ans[i][j] = 1e7
            for k in range(i, j):
                ans[i][j] = min(ans[i][j], ans[i][k] + ans[k + 1][j] +
                                rc_info[i - 1] * rc_info[k] * rc_info[j])

    return ans[1][mat_num]


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    mat_num = int(_input[0])
    mat_info = tuple(map(lambda x: x.split(), _input[1:]))
    # assert len(mat_info) == mat_num

    ans = [[0] * (mat_num + 1) for _ in range(mat_num + 1)]
    print(mat_mul_opt(mat_info))

Python: 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 i in range(n):
  for r in range(n-i-1):
   c=r+i+1
   for j in range(r+1,c):
    x=m[r][j]+m[j][c]+p[r]*p[j]*p[c]
    if 1>m[r][c]or m[r][c]>x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()