Problem:
 Score : 400 points    Problem Statement There is a grid with N rows and N columns of squares. Let (i,j) be the square at the i -th row from the top and the j -th column from the left.  These squares have to be painted in one of the C colors from Color 1 to Color C . Initially, (i,j) is painted in Color c_{i,j} .  We say the grid is a good grid when the following condition is met for all i,j,x,y satisfying 1 \leq i,j,x,y \leq N :   If (i+j) \% 3=(x+y) \% 3 , the color of (i,j) and the color of (x,y) are the same.  If (i+j) \%  3 \neq (x+y) \% 3 , the color of (i,j) and the color of (x,y) are different.   Here, X \% Y represents X modulo Y .  We will repaint zero or more squares so that the grid will be a good grid.  For a square, the wrongness when the color of the square is X before repainting and Y after repainting, is D_{X,Y} .  Find the minimum possible sum of the wrongness of all the squares.      Constraints  1 \leq N \leq 500  3 \leq C \leq 30  1 \leq D_{i,j} \leq 1000 (i \neq j),D_{i,j}=0 (i=j)  1 \leq c_{i,j} \leq C  All values in input are integers.         Input Input is given from Standard Input in the following format:  N  C  D_{1,1}  ...  D_{1,C}  :  D_{C,1}  ...  D_{C,C}  c_{1,1}  ...  c_{1,N}  :  c_{N,1}  ...  c_{N,N}       Output If the minimum possible sum of the wrongness of all the squares is x , print x .        Sample Input 1 2 3
0 1 1
1 0 1
1 4 0
1 2
3 3      Sample Output 1 3   Repaint (1,1) to Color 2 . The wrongness of (1,1) becomes D_{1,2}=1 .  Repaint (1,2) to Color 3 . The wrongness of (1,2) becomes D_{2,3}=1 .  Repaint (2,2) to Color 1 . The wrongness of (2,2) becomes D_{3,1}=1 .   In this case, the sum of the wrongness of all the squares is 3 .  Note that D_{i,j} \neq D_{j,i} is possible.       Sample Input 2 4 3
0 12 71
81 0 53
14 92 0
1 1 2 1
2 1 1 2
2 2 1 3
1 1 2 2      Sample Output 2 428

Solution (Python):
n,c=map(int,input().split())
arrd=[list(map(int,input().split())) for i in range(c)]
arrc=[list(map(int,input().split())) for i in range(n)]
field = [[0,0,0] for _ in range(c+1)]
ans = 10**9

for i in range(n):
  for j in range(n):
    field[arrc[i][j]][(i+j)%3] += 1
    
for p in range(1, c+1):
  for q in range(1, c+1):
    for r in range(1, c+1):
      if q != p:
        if r != p and r != q:
          tmp = 0
          for i in range(1, c+1):
            tmp += field[i][0]*arrd[i-1][p-1]
            tmp += field[i][1]*arrd[i-1][q-1]
            tmp += field[i][2]*arrd[i-1][r-1]
          ans = min(tmp, ans)
          
print(ans)

Solution (Python):
import collections

def main():
    N, C = map(int, input().split())
    D = []
    for _ in range(C):
        D.append(list(map(int, input().split())))
    grid = []
    for _ in range(N):
        grid.append(list(map(int, input().split())))

    if N == 1: return 0

    color = collections.defaultdict(dict)
    for i in range(N):
        for j in range(N):
            c = grid[i][j]
            k = (i+j+2) % 3
            color[k][c] = color[k].get(c, 0) + 1

    cost = []
    for k in color:
        temp = []
        for c1 in range(1, C+1):
            v = 0
            for c2 in color[k]:
                v += D[c2-1][c1-1] * color[k][c2]
            temp.append(v)
        cost.append(temp)

    
    
    ans = float('inf')
    for c1 in range(C):
        for c2 in range(C):
            for c3 in range(C):
                if c1 != c2 and c2 != c3 and c3 != c1:
                    ans = min(ans, cost[0][c1]+cost[1][c2]+cost[2][c3])
    return ans


if __name__ == '__main__':
    print(main())

Solution (Python):
def main():
    N, C = map(int, input().split())
    D = [list(map(int, input().split())) for _ in range(C)]
    c = [list(map(int, input().split())) for _ in range(N)]

    cost = [[0] * C for j in range(3)]
    
    for k in range(C):
        for i in range(N):
            for j in range(N):
                cost[(i+j)%3][k] += D[c[i][j]-1][k]

    
    ans = float('inf')
    for i in range(C):
        for j in range(C):
            for k in range(C):
                if i != j and j != k and k != i:
                    ans = min(ans, cost[0][i] + cost[1][j] + cost[2][k])

    print(ans)





main()

Solution (Python):
from itertools import permutations as 敬語使うべきじゃん
N, C = map(int, input().split())
D = [[0] * (C + 1)] + [[0] + list(map(int, input().split())) for _ in range(C)]
c = [[0] * (N + 1)] + [[0] + list(map(int, input().split())) for _ in range(N)]


group = [[] for _ in range(3)]
for i in range(1, N + 1):
  for j in range(1, N + 1):
    m = (i + j) % 3
    group[m].append(c[i][j])




costs = [[0] * (C + 1) for _ in range(3)]
for i in range(3):
  for color in range(1, C + 1):
    temp = 0
    for j in range(len(group[i])):
      temp += D[group[i][j]][color]
    costs[i][color] = temp

res = 10 ** 10
for per in list(敬語使うべきじゃん(list(range(1, C + 1)), 3)):
  
  
  i, j, k = per[0], per[1], per[2]
  res = min(res, costs[0][i] + costs[1][j] + costs[2][k])
print(res)

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

mod = [[], [], []]

for i in range(N):
    for j in range(N):
        mod[(i+j)%3].append(c[i][j])

from collections import Counter

c = []
for i in range(3):
    c.append(Counter(mod[i]))

ans = float("inf")
for c_i in range(C):
    for c_j in range(C):
        if c_j == c_i:
            continue
        for c_k in range(C):
            if c_k == c_i or c_k == c_j:
                continue
            li = [c_i, c_j, c_k]
            sm = 0
            for i in range(3):
                counter = c[i]
                for k, v in counter.items():
                    sm += d[k-1][li[i]] * v

            ans = min(ans, sm)

print(ans)

Solution (Python):
import itertools
N, C = map(int, input().split())
D = []
for i in range(C):
  Ds = list(map(int, input().split()))
  D.append(Ds)
c = []
for i in range(N):
  cs = list(map(int, input().split()))
  cs = [c-1 for c in cs]
  c.append(cs)
ns = [[0]*C for i in range(3)]
for i in range(N):
  for j in range(N):
    ns[(i+j)%3][c[i][j]] += 1

rs = []
for c0, c1, c2 in itertools.permutations(range(C), 3):
  r = 0
  for i in range(C):
    r += D[i][c0]*ns[0][i]
    r += D[i][c1]*ns[1][i]
    r += D[i][c2]*ns[2][i]
  rs.append(r)
r = min(rs)
print(r)

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

colordata = [[0]*C for i in range(3)]
for i in range(N):
    for j in range(N):
        colordata[(i+j)%3][c[i][j]-1] += 1



ans = 10**30

for color1 in range(C):
    for color2 in range(C):
        if color2 == color1:continue
        for color3 in range(C):
            if color1 == color3 or color2 == color3:continue
            now = 0
            for i in range(C):
                now += data[i][color1]*colordata[0][i]
            for i in range(C):
                now += data[i][color2]*colordata[1][i]
            for i in range(C):
                now += data[i][color3]*colordata[2][i]
            ans = min(ans,now)

print(ans)

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for i in range(C)]
c = [list(map(int, input().split())) for i in range(N)]
r = [[(i + j + 2) % 3 for j in range(N)] for i in range(N)]
c0 = []
c1 = []
c2 = []
ans = 1000 * 500 * 500

for i in range(N):
    for j in range(N):
        if r[i][j] == 0:
            c0.append(c[i][j])
        elif r[i][j] == 1:
            c1.append(c[i][j])
        else:
            c2.append(c[i][j])

d0 = []

for i in range(C):
    d = 0
    for j in c0:
        d += D[j - 1][i]
    d0.append(d)

d1 = []
for i in range(C):
    d = 0
    for j in c1:
        d += D[j - 1][i]
    d1.append(d)

d2 = []
for i in range(C):
    d = 0
    for j in c2:
        d += D[j - 1][i]
    d2.append(d)

for i in range(C):
    for j in range(C):
        for k in range(C):
            if i != j and j != k and k != i:
                ans = min(ans, d0[i] + d1[j] + d2[k])

print(ans)

Solution (Python):
def main():
    import itertools
    import sys
    input = sys.stdin.readline
    
    from collections import defaultdict
    
    N,C = map(int,input().split())
    
    D = [list(map(int,input().split())) for i in range(C)]
    c = [list(map(int,input().split())) for i in range(N)]
    
    ans = float("inf")
    zero = defaultdict(int)
    one = defaultdict(int)
    two = defaultdict(int)
    
    for i in range(N):
        for j in range(N):
            if (i+j)%3 == 0:
                zero[c[i][j]] += 1
            if (i+j)%3 == 1:
                one[c[i][j]] += 1
            if (i+j)%3 == 2:
                two[c[i][j]] += 1
    
    L = [i for i in range(1,C+1)]
    for i, j, k in itertools.permutations(L, 3):
        tmp = 0
        for l in range(1,C+1):
            tmp += D[l-1][i-1]*zero[l] + D[l-1][j-1]*one[l] + D[l-1][k-1]*two[l]
        if tmp < ans:
             ans = tmp
    print(ans)
    
main()

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return sys.stdin.readline().strip()
INF = 10 ** 18
MOD = 10 ** 9 + 7

def main(): 
    N, C = LI()
    D = [[] for _ in range(C)]
    for i in range(C):
        D[i] = LI()
    color = [[] for _ in range(N)]
    for i in range(N):
        color[i] = LI()

    
    counters = [[0 for _ in range(C+1)] for _ in range(3)]
    for i in range(N):
        for j in range(N):
            counters[(i+j)%3][color[i][j]] += 1
    

    sums = [sum(i) for i in counters]

    
    import itertools
    def takemin(variable, val): variable = min(variable, val)
    iwakan = INF
    for selected_cols in itertools.permutations(range(1,C+1), 3):  
        sum_ = 0
        for to_, counter  in zip(selected_cols, counters):  
            for from_, num in enumerate(counter):  
                if from_ == 0: continue
                sum_ += D[from_-1][to_-1] * num
        iwakan = min(iwakan, sum_)
    print(iwakan)

main()

Solution (Python):
import itertools
n,c=map(int,input().split())
ld=[list(map(int,input().split())) for i in range(c)]
lc=[list(map(int,input().split())) for i in range(n)]
ct=[[0 for i in range(c)] for i in range(3)]
for i in range(n):
  for j in range(n):
    ct[(i+j+2)%3][lc[i][j]-1]+=1
L=list(itertools.permutations([i for i in range(c)],3))
ans=[]
for i in range(len(L)):
  ct2=0
  for j in range(3):
    for k in range(c):
      ct2+=ld[k][L[i][j]]*ct[j][k]
  ans.append(ct2)
print(min(ans))

Solution (Python):
import itertools
n,c=map(int,input().split())
ld=[list(map(int,input().split())) for i in range(c)]
lc=[list(map(int,input().split())) for i in range(n)]
ct=[[0 for i in range(c)] for i in range(3)]
for i in range(n):
  for j in range(n):
    ct[(i+j+2)%3][lc[i][j]-1]+=1
L=list(itertools.permutations([i for i in range(c)],3))
ans=[]
for i in range(len(L)):
  ct2=0
  for j in range(3):
    for k in range(c):
      ct2+=ld[k][L[i][j]]*ct[j][k]
  ans.append(ct2)
print(min(ans))

Solution (Python):
import itertools

n, c = [ int(v) for v in input().split() ]
d_list = [ [ int(v) for v in input().split() ] for i in range(c) ]
c_list = [ [ int(v)-1 for v in input().split() ] for i in range(n) ]
change_list = [ [0,0,0] for i in range(c) ]

for k in range(c):
    x, y, z = 0, 0, 0
    for i in range(n):
        for j in range(n):
            if (i + j) % 3 == 0:
                x += d_list[c_list[i][j]][k]
            elif (i + j) % 3 == 1:
                y += d_list[c_list[i][j]][k]
            elif (i + j) % 3 == 2:
                z += d_list[c_list[i][j]][k]
    change_list[k] = [x, y, z]

ans = 10**9
for i in itertools.permutations(range(c),3):
    x, y, z = i
    ans = min(ans, change_list[x][0] + change_list[y][1] + change_list[z][2])
print(ans)

Solution (Python):

N,C = map(int,input().split())
D = [list(map(int,input().split())) for i in range(C)]
c = [list(map(int,input().split())) for i in range(N)]
for i in range(N):
    for j in range(N):
        c[i][j]-=1
    

mod3 = [[0 for i in range(C)] for j in range(3)]
for i in range(N):
    for j in range(N):
        mod3[(i+j)%3][c[i][j]]+=1
        
c3 = [[0 for i in range(C)] for j in range(3)]
for i in range(3):
    for j in range(C):
        kari = 0
        for k in range(C):
            kari+=mod3[i][k]*D[k][j]
        c3[i][j] = kari
        
inf = float("inf")
MIN = inf

for i in range(C):
    C1 = c3[0][i]
    for j in range(C):
        if j != i:
            C2 = c3[1][j]
            for k in range(C):
                if k != i and k != j:
                    C3 = c3[2][k]
                    MIN = min(MIN,C1+C2+C3)
                    
                
if MIN != inf:
    print(MIN)
else:
    print(0)

Solution (Python):
import collections
import itertools


N,C = list(map(int,input().split(" ")))

Ds = []

for i in range(C):
    Ds.append(list(map(int,input().split(" "))))


grid = []
for i in range(N):
    grid.append(list(map(int,input().split(" "))))
color_gird_count = [[0 for _ in range(C + 1)] for _ in range(3)]

for i in range(N):
    for j in range(N):
        c = grid[i][j]
        amari = (i + j + 2) % 3
        color_gird_count[amari][c] += 1
col_val = itertools.permutations(range(1,C + 1),3)
ans = 10** 23
for col in col_val: 
    cot = 0
    for i in range(3):
        for from_c in range(0,C):
           cot += color_gird_count[i][from_c + 1] * Ds[from_c ][col[i] -1 ]
    ans = min(ans,cot)

print(ans)

Solution (Python):

N,C = map(int,input().split())

D = []

for i in range(C):

    d = list(map(int,input().split()))

    D.append(d)

c = []

for i in range(N):

    cc = list(map(int,input().split()))
    c.append(cc)


lis1 = []
lis2 = []
lis3 = []

for c1 in range(C):

    c1 += 1

    now = 0

    for i in range(N):

        for j in range(N):

            if (i + j) % 3 == 0 and c[i][j] != c1:

                now += D[c[i][j]-1][c1-1]

    lis1.append(now)


for c2 in range(C):

    c2 += 1

    now = 0

    for i in range(N):

        for j in range(N):

            if (i + j) % 3 == 1 and c[i][j] != c2:

                now += D[c[i][j]-1][c2-1]

    lis2.append(now)


for c3 in range(C):

    c3 += 1

    now = 0

    for i in range(N):

        for j in range(N):

            if (i + j) % 3 == 2 and c[i][j] != c3:

                now += D[c[i][j]-1][c3-1]

    lis3.append(now)


ans = float("inf")

for i in range(C):

    for j in range(C):

        for k in range(C):


            if i == j or j == k or k == i :
                continue;

            ans = min(ans,lis1[i] + lis2[j] + lis3[k])

print (ans)

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

def main():
    N,C = map(int,input().split())
    D = [list(map(int,input().split())) for _ in range(C)]
    c = [list(map(int,input().split())) for _ in range(N)]
    mod_0 = [0 for _ in range(C)]
    mod_1 = [0 for _ in range(C)]
    mod_2 = [0 for _ in range(C)]
    for i in range(N):
        for j in range(N):
            if (i+j)%3 == 0:
                mod_2[c[i][j]-1] += 1
            if (i+j)%3 == 1:
                mod_0[c[i][j]-1] += 1
            if (i+j)%3 == 2:
                mod_1[c[i][j]-1] += 1
    INF = 10**10
    ans = INF
    for i in range(C):
        for j in range(C):
            if i == j:
                continue
            for k in range(C):
                if i == k or j == k:
                    continue
                ans = min(ans,sum(mod_0[n]*D[n][i] for n in range(C))+\
                              sum(mod_1[n]*D[n][j] for n in range(C))+\
                              sum(mod_2[n]*D[n][k] for n in range(C)))
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
def main():
    N,C = map(int,input().split())
    D = [list(map(int,input().split())) for _ in range(C)]
    c = [list(map(int,input().split())) for _ in range(N)]
    mod_0 = [0 for _ in range(C)]
    mod_1 = [0 for _ in range(C)]
    mod_2 = [0 for _ in range(C)]
    for i in range(N):
        for j in range(N):
            if (i+j)%3 == 0:
                mod_2[c[i][j]-1] += 1
            if (i+j)%3 == 1:
                mod_0[c[i][j]-1] += 1
            if (i+j)%3 == 2:
                mod_1[c[i][j]-1] += 1
    INF = 10**10
    ans = INF
    for i in range(C):
        for j in range(C):
            if i == j:
                continue
            for k in range(C):
                if i == k or j == k:
                    continue
                ans = min(ans,sum(mod_0[n]*D[n][i] for n in range(C))+\
                              sum(mod_1[n]*D[n][j] for n in range(C))+\
                              sum(mod_2[n]*D[n][k] for n in range(C)))
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
import numpy as np
from itertools import permutations

N, C = map(int, input().split())
D2d = np.array([list(map(int, input().split())) for _ in range(C)])
c2d = [list(map(int, input().split())) for _ in range(N)]

colors = [np.array([0 for _ in range(C)]) for i in range(3)]
for i in range(N) :
    for j in range(N) :
        colors[(i+j)%3][c2d[i][j]-1] += 1

ans = np.inf
for c0, c1, c2 in permutations(range(C), 3) :
    a = np.sum(D2d[:, c0]*colors[0]\
              +D2d[:, c1]*colors[1]\
              +D2d[:, c2]*colors[2])
    if a < ans :
        ans = a
print(ans)

Solution (Python):
N,C=map(int,input().split())
D=[list(map(int,input().split())) for _ in [0]*C]
c=[list(map(int,input().split())) for _ in [0]*N]
t=[[0]*C for _ in [0]*3]
for i in range(N):
    for j in range(N):
        t[(i+j)%3][c[i][j]-1]+=1
s=float('inf')
for i in range(C):
    for j in range(C):
        if j==i:continue
        for k in range(C):
            if k==i or k==j:continue
            s=min(s,sum(t[0][n]*D[n][i] for n in range(C))\
                   +sum(t[1][n]*D[n][j] for n in range(C))\
                   +sum(t[2][n]*D[n][k] for n in range(C)))
print(s)

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

def main():
    state = [[0 for _ in range(C)] for _ in range(3)]
    for c in range(C):
        for w in range(N):
            for h in range(N):
                cost = D[grid[h][w]-1][c]
                state[(h+w)%3][c] += cost

    for c1 in range(C):
        for c2 in range(C):
            if c1 == c2:
                continue
            for c3 in range(C):
                if c3 == c1 or c3 == c2:
                    continue
                cost = state[0][c1] + state[1][c2] + state[2][c3]
                if c1 == 0 and c2 == 1 and c3 == 2:
                    ans = cost
                    continue
                ans = min(cost, ans)
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):

import sys, math, fractions, itertools


def solve(N: int, C: int, D: "List[List[int]]", c: "List[List[int]]"):
    """
    (x+y)%3が等しければ色も等しいので良いグリッドには色は3色しかない。
    これを利用して30C3種類全探索。
    """
    t = [[0 for _ in range(30)] for _ in range(3)]
    for i in range(N):
        for j in range(N):
            t[(i+j)%3][c[i][j]-1] += 1

    res = 1 << 30
    for i in range(C):
        for j in range(C):
            if i != j:
                for k in range(C):
                    if i != k and j != k:
                        tt = 0
                        for l in range(C):
                            tt += D[l][i] * t[0][l]
                        for l in range(C):
                            tt += D[l][j] * t[1][l]
                        for l in range(C):
                            tt += D[l][k] * t[2][l]
                        if tt < res:
                            res = tt
    print(res)
    return



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    C = int(next(tokens))  
    D = [ [ int(next(tokens)) for _ in range(C) ] for _ in range(C) ]  
    c = [ [ int(next(tokens)) for _ in range(N) ] for _ in range(N) ]  
    solve(N, C, D, c)

if __name__ == '__main__':
    main()

Solution (Python):
import numpy as np
N, C = map(int,input().split())
D = np.array(list(list(map(int,input().split()))for i in range(C)))
c = list(list(map(int,input().split()))for i in range(N))
A = [np.array([0]*C) for i in range(3)]
for i in range(N):
    for j in range(N):
        A[(i+j)%3][c[i][j]-1] += 1
H = [[[(A[j]*D[:,i]).sum(),i] for i in range(C)] for j in range(3)]
X = [[]for i in range(3)]
for i in range(3):
    X[i] = sorted(H[i])[:3]
ans = float('inf')
for a,i in X[0]:
    for b,j in X[1]:
        for c,k in X[2]:
            if i != j != k != i:
                ans = min(ans,a+b+c)
print(ans)

Solution (Python):







N, C = map(int, input().split())

D = [[int(x) for x in input().split()] for i in range(C)]
grid = [[int(x) for x in input().split()] for i in range(N)]

from collections import Counter
groups = [Counter(), Counter(), Counter()]
for x in range(N):
    for y in range(N):
        groups[(x + y) % 3][grid[x][y]] += 1



from itertools import permutations
import sys
m = 500 * 500 * 2000
for c1, c2, c3 in permutations(list(range(0, C)), 3):
    score = sum(D[c-1][c1] *cnt for c, cnt in groups[0].items())
    score += sum(D[c-1][c2] *cnt for c, cnt in groups[1].items())
    score += sum(D[c-1][c3] *cnt for c, cnt in groups[2].items())
    m = min(m, score)

print(m)

Solution (Python):
N, C = map(int, input().split())

D = [[int(x) for x in input().split()] for i in range(C)]
grid = [[int(x) for x in input().split()] for i in range(N)]

from collections import Counter
groups = [Counter(), Counter(), Counter()]
for x in range(N):
    for y in range(N):
        groups[(x + y) % 3][grid[x][y]] += 1



from itertools import permutations
import sys
m = 500 * 500 * 2000
for c1, c2, c3 in permutations(list(range(0, C)), 3):
    score = sum(D[c-1][c1] *cnt for c, cnt in groups[0].items())
    score += sum(D[c-1][c2] *cnt for c, cnt in groups[1].items())
    score += sum(D[c-1][c3] *cnt for c, cnt in groups[2].items())
    m = min(m, score)

print(m)

Solution (Python):
INF = 10**18

def choice(c):
    for i in range(c):
        for j in range(c):
            if i == j:
                continue
            for k in range(c):
                if (i != k) and (j != k):
                    yield i,j,k

def solve(n, c, D, C):
    P = [{},{},{}]
    for y in range(n):
        for x in range(n):
            i = (x+y) % 3
            k = C[y][x] - 1
            if not k in P[i]:
                P[i][k] = 0
            P[i][k] += 1
    best = INF
    for v in choice(c):
        cur = 0
        for i in range(3):
            t = v[i]
            for s, num in P[i].items():
                cur += D[s][t] * num
        best = min(best, cur)
    return best

n, c = map(int, input().split())
D = [list(map(int, input().split())) for i in range(c)]
C = [list(map(int, input().split())) for i in range(n)]
print(solve(n, c, D, C))

Solution (Python):
n,C=map(int,input().split())
d=[]
c=[]
for i in range(C):
    d.append([int(j) for j in input().split()])
for i in range(n):
    c.append([int(j) for j in input().split()])
l1=[0 for i in range(C+1)]
l2=[0 for i in range(C+1)]
l3=[0 for i in range(C+1)]

for i in range(n):
    for j in  range(n):
        if (i+j+2)%3==0:
            for k in range(1,C+1):
                l1[k]+=d[c[i][j]-1][k-1]
        if (i+j+2)%3==1:
            for k in range(1,C+1):
                l2[k]+=d[c[i][j]-1][k-1]
        if (i+j+2)%3==2:
            for k in range(1,C+1):
                l3[k]+=d[c[i][j]-1][k-1]
ans=10**100
for i in range(1,C+1):
    for j in range(1,C+1):
        for k in range(1,C+1):
            if i!=j and i!=k and j!=k:
                ans=min(ans,l1[i]+l2[j]+l3[k])
print(ans)

Solution (Python):
import math
import copy
from operator import mul
from functools import reduce
from collections import defaultdict
from collections import Counter
from collections import deque

from itertools import product

from itertools import permutations

from itertools import combinations

from itertools import accumulate
from bisect import bisect_left, bisect_right

import re







def inside(y, x, H, W):
    return 0 <= y < H and 0 <= x < W


dy = [0, -1, 0, 1]
dx = [1, 0, -1, 0]
 
def i_inpl(): return int(input())
def l_inpl(): return list(map(int, input().split()))
def line_inpl(x): return [i_inpl() for _ in range(x)]

INF = int(1e50)
MOD = int(1e9)+7 


def create_grid(H, W, value = 0):
    return [[ value for _ in range(W)] for _ in range(H)]



def main():
    N, C = l_inpl()
    D = [ l_inpl() for _ in range(C) ]
    c = []
    for _ in range(N):
        ci = l_inpl()
        ci = [ i-1 for i in ci ] 
        c.append(ci)

    
    t = create_grid(3, C)
    for ci in range(C):
        for i in range(N):
            for j in range(N):
                t[(i+j)%3][ci] += D[c[i][j]][ci]

    ans = INF
    for i in range(C):
        for j in range(C):
            for k in range(C):
                if i == j or j == k or k == i:
                    continue
                tmp = 0
                tmp += t[0][i]
                tmp += t[1][j]
                tmp += t[2][k]
                ans = min(ans, tmp)
    
    print(ans)
if __name__ == "__main__":
    main()

Solution (Python):

N, C = map(int, input().split())
D = [list(map(int, input().split())) for i in range(C)]
c = [list(map(int, input().split())) for i in range(N)]

G1 = [0]*C
G2 = [0]*C
G3 = [0]*C
a = int(0)

for i in range(N):
    for j in range(N):
        if (i + j) % 3 ==2:
            G1[c[i][j]-1] += 1
        elif (i + j) % 3 == 0:
            G2[c[i][j]-1] += 1
        else:
            G3[c[i][j]-1] += 1
ans_candi = []


for i1 in range(C):
    for i2 in range(C):
        for i3 in range(C):
            t = int(0)
            if i1!=i2 and i2!=i3 and i3!=i1:
                for j in range(C):
                    t += D[j][i1]*G1[j]
                for j in range(C):
                    t += D[j][i2]*G2[j]
                for j in range(C):
                    t += D[j][i3]*G3[j]
                ans_candi.append(t)


print(min(ans_candi))

Solution (Python):
import itertools

N, C = map(int, input().split())
D = [list(map(int, input().split())) for _ in range(C)]
c = [[int(s) - 1 for s in input().split()] for _ in range(N)]

m0 = [0] * C
m1 = [0] * C
m2 = [0] * C
for i, j in itertools.product(range(N), repeat=2):
    if (i + j) % 3 == 0: m0[c[i][j]] += 1
    if (i + j) % 3 == 1: m1[c[i][j]] += 1
    if (i + j) % 3 == 2: m2[c[i][j]] += 1

ans = float('inf')
for x, y, z in itertools.permutations(range(C), 3):
    point = 0
    for i in range(C): point += D[i][x] * m0[i]
    for i in range(C): point += D[i][y] * m1[i]
    for i in range(C): point += D[i][z] * m2[i]
    ans = min(ans, point)

print(ans)

Solution (Python):
import itertools
N,C = map(int,input().split(' '))
D = [list(map(int,input().split(' '))) for i in [0]*C]
c = [list(map(int,input().split(' '))) for i in [0]*N]


l = [[],[],[]]
n = 0
for i in range(N):
	for j in range(i+1):
		l[n].append(c[i-j][j])
	n = (n+1) % 3
for i in range(N-1):
	for j in range(N-i-1):
		l[n].append(c[i+j+1][N-j-1])
	n = (n+1) % 3

d1,d2,d3 = [[sum([D[j-1][i] for j in l[n]]) for i in range(C)] for n in range(3)]

ans = 1000*500*500
colors = list(range(C))
for c1,c2,c3 in itertools.permutations(colors,3):
	ans = min(ans,d1[c1] + d2[c2] + d3[c3])
print(ans)

Solution (Python):
from itertools import combinations, permutations, chain

N, C = map(int, input().split())
D = [[0] * (C + 1)]
for _ in range(C):
    a = [0]
    a.extend(list(map(int, input().split())))
    D.append(a)
c = [list(map(int, input().split())) for _ in range(N)]


color = [[0 for _ in range(C + 1)] for _ in range(3)]
for row in range(1, len(c) + 1):
    for col in range(1, len(c[row - 1]) + 1):
        g = (row + col) % 3
        color[g][c[row - 1][col - 1]] += 1


def count():
    for x, y, z in combinations(range(C), 3):
        for a, b, c in permutations([x + 1, y + 1, z + 1]):
            yield a, b, c


ans = float('inf')
for c1, c2, c3 in count():
    cost = 0
    for i in range(1, C + 1):
        cost += color[0][i] * D[i][c1]
    for i in range(1, C + 1):
        cost += color[1][i] * D[i][c2]
    for i in range(1, C + 1):
        cost += color[2][i] * D[i][c3]
    ans = min(ans, cost)

print(ans)

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

N, C = map(int, input().split())

grid_array = [[0] * C for _ in range(3)]

D_array = [list(map(int, input().split())) for _ in range(C)]

for i in range(N):
    C_array = map(int, input().split())
    for j, c in enumerate(C_array):
        grid_array[(i+j) % 3][c-1] += 1



cost_array = [[0] * C for _ in range(3)]
for i in range(3):
    for j in range(C):
        cost = 0
        for k in range(C):
            cost += grid_array[i][k] * D_array[k][j]
        cost_array[i][j] = cost

ans = 10 ** 20

for i in range(C):
    for j in range(C):
        if j == i:
            continue
        for k in range(C):
            if k == i or k == j:
                continue
            ans = min(ans, cost_array[0][i] +
                      cost_array[1][j] + cost_array[2][k])
print(ans)

Solution (Python):
N, C = map(int, input().split())

D = []
c = []

for i in range(C) :
    line = list(map(int, input().split()))
    D.append(line)
for i in range(N) :
    line = list(map(int, input().split()))
    c.append(line)

colorCount = [[0 for _ in range(C + 1)] for _ in range(3)]  
for i in range(N) :
    for j in range(N) :
        colorCount[(i + j + 2) % 3][c[i][j]] += 1

ans = float('inf')
for firstColor in range(1, C + 1) :
    for secondColor in range(1, C + 1) :
        for thirdColor in range(1, C + 1) :
            if firstColor == secondColor or secondColor == thirdColor or thirdColor == firstColor :
                continue
            cost = 0
            for dist, toColor in enumerate([secondColor, thirdColor, firstColor]) :
                for fromColor in range(1, C + 1) :
                    if toColor == fromColor :
                        continue
                    cost += colorCount[dist][fromColor] * D[fromColor - 1][toColor - 1]
            ans = min(ans, cost)

print(ans)

Solution (Python):



import sys
import math
import bisect
from heapq import heappush, heappop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10**9 + 7

n,c = map(int,input().split())
d = [list(map(int,input().split())) for _ in range(c)]
g = [list(map(int,input().split())) for _ in range(n)]

cnt0 = [0]*30
cnt1 = [0]*30
cnt2 = [0]*30

for y in range(1,n+1):
    for x in range(1,n+1):
        if (x+y) % 3 == 0:
            cnt0[g[y-1][x-1]-1] += 1
        elif (x+y) % 3 == 1:
            cnt1[g[y-1][x-1]-1] += 1
        else:
            cnt2[g[y-1][x-1]-1] += 1

l = list(permutations(range(c),3))
ans = float('inf')
for c0,c1,c2 in l:
    preans = 0
    for i in range(c):
        preans += d[i][c0] * cnt0[i]
        preans += d[i][c1] * cnt1[i]
        preans += d[i][c2] * cnt2[i]
    ans = min(ans,preans)
print(ans)