Problem:
Matrix-chain Multiplication The goal of the matrix-chain multiplication problem is to find the most efficient way to multiply given $n$ matrices $M_1, M_2, M_3,...,M_n$. Write a program which reads dimensions of $M_i$, and finds the minimum number of scalar multiplications to compute the maxrix-chain multiplication $M_1M_2...M_n$. Input In the first line, an integer $n$ is given. In the following $n$ lines, the dimension of matrix $M_i$ ($i = 1...n$) is given by two integers $r$ and $c$ which respectively represents the number of rows and columns of $M_i$. Output Print the minimum number of scalar multiplication in a line. Constraints  $1 \leq n \leq 100$  $1 \leq r, c \leq 100$  Sample Input 1 6
30 35
35 15
15 5
5 10
10 20
20 25 Sample Output 1 15125

Solution (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 not 0<m[r][c]<=x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()

Solution (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 not 0<m[r][c]<x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()

Solution (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 not 0<m[r][c]<x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()

Solution (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 not 0<m[r][c]<x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()

Solution (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 not 0<m[r][c]<=x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()

Solution (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 not 0<m[r][c]<=x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()

Solution (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 not 0<m[r][c]<=x:m[r][c]=x
 print(m[r][c])
if'__main__'==__name__:s()

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

Solution (Python):

from functools import lru_cache


@lru_cache(maxsize=None)
def multi(ms):
    """Matix multiplication. returns minimum number of scalar
    multiplications to compute all matrix multiplications.

    >>> multi(((30, 35), (35, 15), (15, 5), (5, 10), (10, 20), (20, 25)))
    15125
    """
    size = len(ms)
    if size <= 1:
        return 0
    elif size == 2:
        r1, c1 = ms[0]
        r2, c2 = ms[1]
        return c1 * r1 * c2

    costs = []
    for i in range(size-1):
        cost = ms[i][1] * ms[0][0] * ms[-1][1]
        costs.append(multi(ms[:i+1]) + multi(ms[i+1:]) + cost)

    return min(costs)


def run():
    n = int(input())
    ms = []

    for i in range(n):
        m = tuple([int(x) for x in input().split()])
        ms.append(m)

    print(multi(tuple(ms)))


if __name__ == '__main__':
    run()

Solution (Python):
INFTY = float('inf')

n = int(input())
M = [[0 for i in range(n)] for i in range(n)]
p = []

for i in range(n):
    r, c = list(map(int, input().split(' ')))
    if i == 0: p.append(r)
    p.append(c)

for i in range(n-1):
    M[i][i+1] = p[i]*p[i+1]*p[i+2]

for gap in range(2,n): 
    for i in range(n-gap):
        j = i+gap
        M[i][j] = INFTY
        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])

Solution (Python):
N = int(input())
P = []
for i in range(N):
    r, c = map(int, input().split())
    if i == 0:
        P.append(r)
    P.append(c)


def matrix_chain():
    dp = [[None for j in range(N+1)] for i in range(N+1)]
    for i in range(1, N+1):
        dp[i][i] = 0

    for l in range(2, N+1):
        for i in range(1, N-l+2):
            j = i + l - 1
            dp[i][j] = 1000000000000000
            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])

    return dp[1][N]


def main():
    print(matrix_chain())


if __name__ == '__main__':
    main()

Solution (Python):
import functools
 
 
@functools.lru_cache(maxsize=None)
def rec(l, r):
    
    if l+1 == r:
        return 0
    ret = INF
    for mid in range(l+1, r):
        ret = min(ret, rec(l, mid) + rec(mid, r) + R[l] * R[mid] * C[r-1])
    return ret
 
INF = 10**9
N = int(input())
R, C = [], []
for i in range(N):
    r, c = map(int, input().split())
    R.append(r), C.append(c)
print(rec(0, N))

Solution (Python):

import functools
INF = 10**9
n = int(input())
p = list(map(int, input().split()))
for i in range(n - 1):
    p.append(int(input().split()[1]))


@functools.lru_cache(maxsize=None)
def matrix_chain_multiplication(i, j):
    if i == j:
        return 0

    tmp = INF
    for k in range(i, j):
        tmp = min(
            tmp,
            matrix_chain_multiplication(i, k) +
            matrix_chain_multiplication(k + 1, j) + p[i - 1] * p[k] * p[j])
    return tmp


print(matrix_chain_multiplication(0, n - 1))

Solution (Python):
import sys
n = int(input())
input_list = [[int(i) for i in str.split()] for str in sys.stdin.read().splitlines()]
size_list = [0 for i in range(n+1)]
size_list[0] = input_list[0][0]
for i in range(1,n+1):
    size_list[i] = input_list[i-1][1]


m = [[float('inf') for i in range(n)] for j in range(n)]

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

for x in range(n):
    i, j = 0, x
    for y in range(n-x):
        for k in range(i, j):
            m[i][j] = min(m[i][j], m[i][k] + m[k+1][j] + size_list[i]*size_list[k+1]*size_list[j+1])
        i, j = i+1, j+1

print(m[0][-1])

Solution (Python):
n = int(input())
p = []
s = input().split()
p.append(int(s[0]))
p.append(int(s[1]))
for _ in range(n - 1):
    s = input().split()
    p.append(int(s[1]))

m = [[-1 for _ in range(n)] for _ in range(n)]
for i in range(n):
    m[i][i] = 0

for l in range(2, n + 1):
    for i in range(0, n - l + 1):
        j = i + l - 1
        for k in range(i, j):
            x = m[i][k] + m[k + 1][j] + p[i] * p[k + 1] * p[j + 1]
            if m[i][j] < 0:
                m[i][j] = x
            elif m[i][j] > x:
                m[i][j] = x

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

Solution (Python):

n = int(input())
m = [[0 for i in range(n)] for j in range(n)]
p = []
for i in range(n):
    p1,p2 = map(int,input().split())
    if i == 0:
        p.append(p1)
    p.append(p2)

def matrixChainMultiplication():
    for i in range(n):
        m[i][i] = 0

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

Solution (Python):

import sys

ROW = 0
COL = 1

def matrixchaincost(M):
    n = len(M)
    cost = [[0 for i in range(n)] for j in range(n)]

    for length in range(2, n+1):
        for i in range(0, n-length+1):
            k = i+length-1
            def f(i,j,k):
                return cost[i][j-1]+cost[j][k]+M[i][ROW]*M[j-1][COL]*M[k][COL]
            cost[i][k] = min([f(i,j,k) for j in range(i+1,k+1)])
    return cost[0][n-1]

n = input()
M = []
for i in range(n):
    M.append(map(int, raw_input().split()))
    
print matrixchaincost(M)

Solution (Python):

from __future__ import division, print_function
from sys import stdin


def main():
    num_mat = int(stdin.readline())
    r = [int(s) for s in stdin.readline().split()]
    for _ in range(num_mat-1):
        _, row = (int(s) for s in stdin.readline().split())
        r.append(row)

    if num_mat < 2:
        print(0)
        return
    elif num_mat < 3:
        print(r[0]*r[1]*r[2])
        return

    M = []
    M.append([0] * num_mat)
    M.append([r[i]*r[i+1]*r[i+2] for i in range(len(M[-1])-1)])

    for i in range(2, num_mat):
        N = []
        for j in range(num_mat-i):
            N.append(min(M[k][j]+M[i-1-k][1+j+k]+r[j]*r[1+j+k]*r[i+1+j]
                         for k in range(i)))
        M.append(N)
    print(M[-1][0])


main()

Solution (Python):
import sys
input = sys.stdin.readline
n = int(input())
p0, p1 = map(int, input().split())
p = [p0, p1]
for _ in range(1, n):
    _, tmp = map(int, input().split())
    p.append(tmp)


dp = [[0]*(n+1) for _ in range(n+1)]


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







for w in range(2, n+1):
    for i in range(1, n+1):
        j = i+w-1
        if j >= n+1:
            continue
        res = 1e30
        for k in range(i, j):
            res = min(
                res,
                dp[i][k] + dp[k+1][j] + p[i-1] * p[k] * p[j]
            )
        dp[i][j] = res
print(dp[1][n])

Solution (Python):
import sys
import math
from collections import defaultdict, deque
from copy import deepcopy
    
input = sys.stdin.readline
def RD(): return input().rstrip()
def F(): return float(input().rstrip())
def I(): return int(input().rstrip())
def MI(): return map(int, input().split())
def MF(): return map(float,input().split())
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float,input().split()))
def Init(H, W, num): return [[num for i in range(W)] for j in range(H)]
def end_of_loop():raise StopIteration
    
    
def main():
    N = I()
    A = [0]*N
    B = [0]*N
    if N == 0:
        sys.exit()
    for i in range(N):
        a, b = MI()
        A[i] = a
        B[i] = b

    D = Init(N, N, 0)
    
    for num1 in range(N-1):
        num2 = num1+1
        a,b,c = A[num1], B[num1], B[num2]
        D[num1][num2] = a*b*c
        D[num2][num1] = a*b*c

    for length in range(2, N):
        for num1 in range(N-length):
            num2 = num1+length
            
            a = A[num1]
            c = B[num2]
            result = float('inf')
            for num3 in range(num1, num2):
                result = min(result, a*B[num3]*c + D[num1][num3] + D[num3+1][num2])
            D[num1][num2] = result
            D[num2][num1] = result
    print(D[0][N-1])
            
if __name__ == "__main__":
    main()

Solution (Python):



n = int(input())

P = []
a, b = [int(i) for i in input().split()]
P.append(a)
P.append(b)
for _ in range(n - 1):
    _, b = [int(i) for i in input().split()]
    P.append(b)

dp = [[None] * (n + 1) for _ in range(n + 1)]  

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

for r in range(2, n + 1):
    for i in range(1, n - r + 2):
        j = i + r - 1
        dp[i][j] = float("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[1][-1])

Solution (Python):
n = int(input())


def memorizer(f):
    memo = [ [None] * n for _ in range(n) ]
    for i in range(n):
        memo[i][i] = 0

    def inner_memo(a, b):
        if memo[a][b] is not None:
            return memo[a][b]
        rslt = memo[a][b] = f(a, b)
        return rslt

    return inner_memo

@memorizer
def minimum(a, b):
    return min(minimum(a, i) + minimum(i + 1, b) + l[a] * l[i + 1] * l[b + 1] for i in range(a, b))



a, b = map(int, input().split())

l = []
l.append(a)
l.append(b)

n1 = n - 1

while n1 != 0:
    a, b = map(int, input().split())
    l.append(b)
    n1 -= 1

print(minimum(0, n - 1))

Solution (Python):
N = int(input())
RC = [tuple(map(int, input().split())) for _ in range(N)]
INF = 10**18

dp = [[INF]*N for _ in range(N)]
for i in range(N):
    for j in range(N):
        if i == j:
            dp[i][j] = 0
for diff in range(2, N+1):
    for i in range(N-diff+1):
        j = i+diff-1
        for k in range(i, j):
            dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]+RC[i][0]*RC[k][1]*RC[j][1])
print(dp[0][N-1])

Solution (Python):
import sys
input = sys.stdin.readline

def matrixChainMultiplication(n):
    for l in range(2, n+1):
        for i in range(1, n-l+2):
            j = i + l - 1
            min_ = 2**21 
            for k in range(i, j):
                value = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
                if min_ > value:
                    min_ = value
            m[i][j] = min_

m = [[0]*(101) for _ in range(101)]
p = [0] * 101
N = int(input())
l0 = list(map(int, input().split()))
p[0] = l0[0]
p[1] = l0[1]
for _ in range(1, N):
    li = list(map(int, input().split()))
    p[_+1] = li[1]
matrixChainMultiplication(N)
print(m[1][N])

Solution (Python):




def kuDP(l,r):
  global dp
  
  if dp[l][r] != -1:
    return dp[l][r]
  
  if l == r:
    dp[l][r] = 0
    return 0
  
  if l+1 == r:
    c = M[l][0]*M[l][1]*M[r][1]
    dp[l][r] = c
    return c
  
  midl = [10**10]*(r-l)
  for mid in range(r-l):
    midl[mid] = kuDP(l,l+mid) + kuDP(l+mid+1,r) + M[l][0]*M[l+mid][1]*M[r][1]
    
  c = min(midl)
  
  dp[l][r] = c
  
  return c

N = int(input())
M = [list(map(int,input().split())) for _ in range(N)]
dp = [[-1]*N for _ in range(N)]
print(kuDP(0,N-1))

Solution (Python):
import sys, os, math, bisect, itertools, collections, heapq, queue, copy, array





sys.setrecursionlimit(10000000)

ii = lambda: int(sys.stdin.buffer.readline().rstrip())
il = lambda: list(map(int, sys.stdin.buffer.readline().split()))
fl = lambda: list(map(float, sys.stdin.buffer.readline().split()))
iln = lambda n: [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)]

iss = lambda: sys.stdin.buffer.readline().decode().rstrip()
sl = lambda: list(map(str, sys.stdin.buffer.readline().decode().split()))
isn = lambda n: [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)]

lcm = lambda x, y: (x * y) // math.gcd(x, y)

MOD = 10 ** 9 + 7
MAX = float('inf')


def main():
    if os.getenv("LOCAL"):
        sys.stdin = open("input.txt", "r")

    N = ii()
    dp = [[0] * (N + 1) for _ in range(N + 1)]
    p = [0] * (N + 1)
    for i in range(N):
        p[i], p[i + 1] = il()

    for l in range(2, N + 1):
        for i in range(1, N - l + 2):
            j = i + l - 1
            dp[i][j] = MAX
            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[1][N])


if __name__ == '__main__':
    main()

Solution (Python):
import sys
read = sys.stdin.read
readline = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 8)
INF = float('inf')
MOD = 10 ** 9 + 7

def matrixChainMultiplication(n,p):
    dp = [[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
            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])
    return dp[1][n]


def main():
    N = int(readline())
    P = []

    for _ in range(N):
        r, c = map(int, readline().split())
        P.append(r)
    P.append(c)

    print(matrixChainMultiplication(N,P))

    


if __name__ == '__main__':
    main()

Solution (Python):
n = int(input())
p = []
a, b = map(int, input().split())
p.append(a)
p.append(b)
for _ in range(n-1):
    a, b = map(int, input().split())
    p.append(b)

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

Solution (Python):
def main():
    n=int(input())
    lst=tuple(tuple(map(int,input().split())) for _ in range(n))

    dp=[[0]*n for _ in range(n)]
    for i in range(1,n):
        for j in range(0,n-i):
            dp[j][j+i]=dp[j+1][j+i]+lst[j][0]*lst[j][1]*lst[j+i][1]
            for k in range(1,i):
                nwork=dp[j][j+k]+dp[j+k+1][j+i]+lst[j][0]*lst[j+k][1]*lst[j+i][1]
                if dp[j][j+i]>nwork : dp[j][j+i]=nwork
    
    print(dp[0][n-1])

main()

Solution (Python):
n = int(input())
m = [list(map(int, input().split())) for _ in range(n)]

p = [m[0][0]]
for i in range(n):
    p.append(m[i][1])

INF = 1 << 60
dp = [[INF] * n for _ in range(n)]

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

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

print(dp[0][-1])

Solution (Python):
N = int(input())
RC = []
for _ in range(N):
    RC.append(list(map(int, input().split())))

dp = {}

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

for w in range(2, N+1):
    for l in range(N-w+1):
        cost = float('inf')
        r = l+w-1
        for m in range(l, r):
            mul = RC[l][0] * RC[m][1] * RC[r][1]
            cost = min(cost, dp[(l, m)]+dp[(m+1,r)] + mul)
        dp[(l, r)] = cost
print(dp[(0, N-1)])

Solution (Python):
import sys
def input():
    return sys.stdin.readline()[:-1]
n = int(input())
A = [list(map(int, input().split())) for _ in range(n)]

p = [A[0][0]] + [A[i][1] for i in range(n)]
m = [[0 for i in range(n+1)] for j in range(n+1)]

for l in range(2,n+1):
    for i in range(1,n-l+1+1):
        j = i + l - 1
        for k in range(i,j):
            x = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
            if not 0<m[i][j]<=x:
                m[i][j] = x
print(m[1][n])

Solution (Python):
INF = 10**10


def rec(l:int, r:int) -> int:
    if dp[l][r] != INF:
        return dp[l][r]
    elif r - l == 1:
        dp[l][r] = 0
        return 0
    elif r - l == 2:
        dp[l][r] = M[l][0] * M[l][1] * M[l+1][1]
        return dp[l][r]
    else:
        for i in range(l+1, r):
            dp[l][r] = min(dp[l][r], rec(l, i) + rec(i, r) + M[l][0] * M[i-1][1] * M[r-1][1])
    return dp[l][r]


if __name__ == "__main__":
    N = int(input())
    M = [tuple(map(int, input().split())) for _ in range(N)]
    dp = [[INF]*(N+1) for _ in range(N+1)]
    print(rec(0, N))

Solution (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): 
    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])

Solution (Python):
N = int(input())

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

dp = [[float("inf")]*N for _ in range(N)]

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

for l in range(1, N):  
    for i in range(N):
        j = i+l
        if j < N:
            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])

Solution (Python):
n = int(input())
INFTY = 10**8

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

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

def matricChainMultiplication(n, p, M):

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

    return M[0][n-1]

print(matricChainMultiplication(n, p, M))

Solution (Python):
import sys

N = 100
n = int(input())

p = [0]*(N+1)
m = [list([0]*(N+1)) for _ in range(N+1)]

for i in range(n):
    p[i],p[i+1]=map(int,input().split())
for l in range(2,n+1):
    for i in range(1,n-l+2):
        j = i+l-1
        m[i][j]=sys.maxsize
        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])

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

for i in range(1, n+1): 
    m[i][i] = 0
for i in range(1, n): 
    m[i][i+1] = r[i-1] * r[i] * r[i+1]
for j in range(2, n): 
    for i in range(1, n-j+1): 
        for k in range(j): 
            
            cost = m[i][i+k] + r[i-1]*r[i+k]*r[i+j] + m[i+k+1][i+j]
            if cost < m[i][i+j]:
                m[i][i+j] = cost
print(m[1][n])

Solution (Python):
N = int(input())
m = []
for i in range(N):
  x,y = map(int,input().split())
  m.append((x,y))

dp = [ [0]*N for _ 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] = float('inf')
    for k in range(i,j):
      m0,m1,m2 = m[i],m[k],m[j]
      
      dp[i][j] = min(dp[i][j], dp[i][k]+dp[k+1][j]+m0[0]*m1[1]*m2[1])

print(dp[0][-1])

Solution (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])

Solution (Python):
n=int(input())
m={}
p=[]

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

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

Solution (Python):
n = int(input())
p = [0]*(n+1)
m = [[None for _ in range(n+1)] for _ in range(n+1)]
for i in range(1,n+1):
    p[i-1],p[i] = map(int,input().split())
    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])

Solution (Python):
import sys

input = sys.stdin.readline
INF = float("inf")


def main():
    n = int(input())
    r = [None] * n
    c = [None] * n
    for i in range(n):
        r[i], c[i] = map(int, input().split())

    dp = [[INF] * n for _ in range(n)]
    for i in range(n):
        dp[i][i] = 0

    for width in range(2, n + 1):
        for i in range(n - width + 1):
            j = i + width - 1
            for m in range(i, j):
                dp[i][j] = min(dp[i][j], dp[i][m] + dp[m + 1][j] + r[i] * c[m] * c[j])

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


if __name__ == "__main__":
    main()

Solution (Python):
def main():
    N = int(input())
    p = []
    for i in range(N):
        a, b = map(int, input().split())
        p.append(a)
    else:
        p.append(b)

    m = [[1e10]*(N+1) for _ in range(N+1)]
    for i in range(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] = 1e10
            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__':
    main()

Solution (Python):
import sys
import itertools

import time
import math
import heapq
 
sys.setrecursionlimit(10 ** 7)
 
from collections import defaultdict
 
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
INF = 10 ** 9 + 7




N = int(input())
M = [0] * N
for i in range(N):
    M[i] = tuple(map(int, input().split()))

dp = [[INF] * (N) for _ in range(N)]
for i in range(N):
    dp[i][i] = 0

def rec(l, r):
    if dp[l][r] != INF:
        return dp[l][r]
    res = INF
    for mid in range(l, r):
        res = min(res, rec(l, mid) + rec(mid + 1, r) + M[l][0] * M[mid][1] * M[r][1])
    dp[l][r] = res
    return res
print(rec(0, N - 1))

Solution (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 for i in range(n+1)] for j in range(n+1)]

for i in range(2, n+1): 
    for j in range(0, n+1-i): 
        dp[j][j+i] = min([dp[j][k]+(r[j]*c[k-1]*c[j+i-1])+dp[k][j+i] for k in range(j+1,j+i)])

print(dp[0][n])

Solution (Python):



import math


def cost(i, j):
    if (i, j) in cost_dict.keys():
        return cost_dict[(i, j)]
    elif i == j:
        cost_dict[(i, j)] = 0
    else:
        mincost = math.inf
        for k in range(i, j):
            estimate = cost(i, k) + cost(k + 1, j) + dims[i - 1] * dims[k] * dims[j]
            mincost = min(estimate, mincost)
        cost_dict[(i, j)] = mincost
    return cost_dict[(i, j)]


if __name__ == '__main__':
    
    n = int(input())
    
    cost_dict = dict()
    
    dims = []
    for _ in range(n - 1):
        first = int(input().split()[0])
        dims.append(first)
    dims.extend(list(map(int, input().split())))
    
    print(cost(1, n))

Solution (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[k+1] * P[j+1], dp[i][j])
print(dp[0][-1])

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

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

def mincost(x,y):
    if dp[x][y]>0:
        return dp[x][y]
    elif x>=y:
        return dp[x][y]
    else:
        res=float('inf')
        for k in range(x,y):
            temp=mincost(x,k)+mincost(k+1,y)+M[x][0]*M[k][1]*M[y][1]
            res=min(res,temp)
        dp[x][y]=res
        return dp[x][y]

print(mincost(0,n-1))

Solution (Python):

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

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

    

dp[0][0]=0
for j in range(1,n):
    for i in range(j,-1,-1):

        if j==i:
            dp[i][j]=0

        else:

            for k in range(j-1,i-1,-1):

                dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+p[i]*p[k+1]*p[j+1])


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

Solution (Python):
n = int(input())
mat = []
for _ in range(n):
    mat.append(list(map(int, input().split())))
inf = int(1e11 + 10)
dp = [[inf]*(n + 1) for _ in range(n + 1)]
for i in range(n):
    dp[i][i] = 0
for l in range(2, n + 1):
    for i in range(n):
        j = i + l - 1
        if i + l > n:
            break
        for k in range(i, j):
            dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + mat[i][0]*mat[k][1]*mat[j][1])
print(dp[0][n - 1])

Solution (Python):
def solve(n,mat):
    dp=[[0]*n for _ in range(n)]
    for kukan in range(1,n):
        for i in range(n-kukan):
            dp[i][i+kukan]=min([dp[i][mid]+dp[mid+1][i+kukan]+mat[i][0]*mat[mid+1][0]*mat[i+kukan][1] for mid in range(i,i+kukan)])
    return dp[0][n-1]

n=int(input())
mat=[tuple(map(int,input().split())) for _ in range(n)]
print(solve(n,mat))

Solution (Python):
def solve(a, b):
    global dp
    if a == b:
        return 0
    elif dp[a][b]:
        return dp[a][b]
    ret = INF
    for i in range(a, b):
        tmp = solve(a, i) + solve(i + 1, b) + c[i] * r[a] * c[b]
        ret = min(ret, tmp)
    dp[a][b] = ret
    return ret

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

INF = float('inf')
dp = [[0 for _ in range(n)] for _ in range(n)]
print(solve(0, n - 1))

Solution (Python):


import sys

N = int(input())

M = []
for n in range(N):
    r, c = map(int, sys.stdin.readline().strip().split())
    if n == 0:
        M.append(r)
    M.append(c)



dp = [[float('inf')] * N for _ in range(N)]
for n in range(N):
    dp[n][n] = 0


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




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

Solution (Python):
n = int(input())
p = [None] * (n+1)
for i in range(n):
  p[i], p[i+1] = map(int, input().split())

INF = 10**18
m = [[None] * n for _ in range(n)]
for i in range(n):
  m[i][i] = 0
  
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]*p[k]*p[j])

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

Solution (Python):
N = int(input())
M = [[int(x) for x in input().split()] for _ in range(N)]

p = []

for m in M:
    p.append(m[0])

p.append(M[-1][1])

dp = [[0] * N for j in range(N)]

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

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

Solution (Python):


import sys
sys.setrecursionlimit(10**7)



def rec(l,r):
    if r-l < 1:
        return 0
    if r-l == 1:
        return M[l][0] * M[r][0] * M[r][1]
    if memo[l][r] != -1:
        return memo[l][r]
    memo[l][r] = min(rec(l, j-1) + rec(j, r) + M[l][0] * M[j-1][1] * M[r][1] for j in range(l+1,r+1))
    return memo[l][r]



N = int(input())
M = []
memo = [[-1]*N for _ in range(N)]

for i in range(N):
    M.append(list(map(int, input().split())))

print(rec(0,N-1))

Solution (Python):
n =int(input())
R = [0]*(n+1)
C = [0]*(n+1)
for u in range(n):
    R[u+1], C[u+1] = map(int, input().split())

INF = 10**18    
dp = [[INF]*(n+1) for _ in range(n+1)]
for i in range(1,n+1):
    dp[i][i] = 0
for l in range(1,n):
    for i in range(1,n+1-l):
        dp[i][i+l] = min(dp[i][k]+ dp[k+1][i+l] + R[i]*C[k]*C[i+l] for k in range(i,i+l))

print(dp[1][n])

Solution (Python):
MAX_R = 100
MAX_C = 100
n = int(input())
mat_list = [list(map(int, input().split())) for _ in range(n)]
dp = [[-1] * (MAX_C + 1) for _ in range(MAX_R + 1)]

def get_min(i, j):
    ans = float('inf')
    if dp[i][j] != -1:
        return dp[i][j]
    if i == j:
        ans = 0
    else:
        for k in range(i, j):
            p = mat_list[i][0]
            q = mat_list[k][1]
            r = mat_list[j][1]
            tmp = get_min(i, k) + get_min(k+1, j) + p*q*r
            if tmp < ans:
                ans = tmp
    dp[i][j] = ans
    return ans

print(get_min(0, n-1))