Go: package main

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

var sc = bufio.NewScanner(os.Stdin)

func nextInt() int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return i
}
func main() {
	sc.Split(bufio.ScanWords)
	var n int
	var M [101][101]int

	n = nextInt()

	P := make([]int, n*2)

	for i := 1; i <= n; i++ {
		P[i-1] = nextInt()
		P[i] = nextInt()
	}
	for l := 2; l <= n; l++ {
		for i := 1; i <= n-l+1; i++ {
			j := i + l - 1
			M[i][j] = 1000000
			for k := i; k <= j-1; k++ {
				M[i][j] = int(math.Min(float64(M[i][j]), float64(M[i][k]+M[k+1][j]+P[i-1]*P[k]*P[j])))
			}
		}
	}
	fmt.Println(M[1][n])
}

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

from sys import maxsize


def irange(start, stop=None):
    if stop:
        return range(start, stop + 1)
    else:
        return range(start + 1)


def count(ms):
    n = len(ms)

    p = [0] * (n + 1)
    for i in range(n):
        p[i] = ms[i][0]
        p[i + 1] = ms[i][1]

    m = [[None] * (n + 1) for _ in irange(n)]
    for i in irange(1, n):
        m[i][i] = 0
    for l in irange(2, n):
        for i in irange(1, n - l + 1):
            j = i + l - 1
            m[i][j] = maxsize
            for k in irange(i, j - 1):
                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]


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

    m = []
    for _ in range(n):
        m.append(tuple(int(x) for x in input().split()))
    c = count(m)
    print(c)


if __name__ == '__main__':
    main()

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

DP = [[0]*N for _ in range(N)]
for l in range(2, N+1): # l は行列の数
    for i in range(0, N):
        j = i + l-1
        if j >= N:
            break
        
        DP_ji = 10**9
        for k in range(i, j):
            DP_ji = min(DP_ji
                        ,DP[k][i] + DP[j][k+1] + r[i]*c[k]*c[j])
        DP[j][i] = DP_ji
print(DP[N-1][0])

Python: n = int(input())
p = [0]*(n+1)
for i in range(1,n+1): p[i-1],p[i] = map(int,input().split())
m = [[0]*(n+1) for _ in range(n+1)]
# 対象とする行列の数l
for l in range(2,n+1):
    # for i in range(n+1): print(m[i])    
    # print("/////////////////////////////////")
    # 対象とする行列の範囲i,j
    # iは1からn-(l-1)まで
    for i in range(1,n-l+2):
        j = i+l-1
        m[i][j] = float("inf")
        # (M_iM_i+1...M_k)(M_k+1...M_j)の乗算回数が最小となるkを探す
        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])

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