Buggy python submission (verdict: Time Limit Exceeded):
import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
# 解説を見てしまったので、せめて再帰ではない方法で
def main():
    n = int(input())
    m = 1 << n  # 総組合せ数
    aa = LLI(n)
    dp = [0] * m
    for s in range(2, m):
        # sのうさぎたちが1グループだった場合
        value = 0
        jj = []
        for i in range(n):
            if not s & 1 << i: continue
            for j in jj:
                value += aa[i][j]
            jj.append(i)
        # 部分集合tとその補集合に分かれる場合
        # 全体集合sから始めて、「1を引く」「sと論理積をとる」を繰り返すことで
        # すべての部分集合を列挙できる
        first = [True] * m
        t = (s - 1) & s
        while first[t] and t > 0:
            value_div = dp[t] + dp[s - t]
            if value_div > value: value = value_div
            first[s - t] = False
            t = (t - 1) & s
        dp[s]=value
    print(dp[m-1])

main()


Fixed submission:
def max_ten(s):
    if memo[s]!="e":
        return memo[s]
    ten = 0
    # 分けない場合の点数
    for ai, ar in enumerate(a[:-1]):
        if s >> ai & 1:
            ten += sum(ar[j] * (s >> j & 1) for j in range(1 + ai, n))
    # 分ける場合の点数
    bubun = (s - 1) & s
    while bubun > 0:
        kari = max_ten(bubun) + max_ten(bubun ^ s)
        if kari > ten:
            ten = kari
        bubun = (bubun - 1) & s
    memo[s] = ten
    return ten


n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
s = (1 << n) - 1
memo = ["e"] * (1 << n)
print(max_ten(s))

Buggy python submission (verdict: Time Limit Exceeded):
import sys

sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep="\n")
def MI(): return map(int, sys.stdin.readline().split())
def LI(): return list(map(int, sys.stdin.readline().split()))
def LLI(rows_number): return [LI() for _ in range(rows_number)]
# 解説を見てしまったので、せめて再帰ではない方法で
def main():
    n = int(input())
    m = 1 << n  # 総組合せ数
    aa = LLI(n)
    dp = [0] * m
    for s in range(2, m):
        # sのうさぎたちが1グループだった場合
        value = 0
        jj = []
        for i in range(n):
            if not s & 1 << i: continue
            for j in jj:
                value += aa[i][j]
            jj.append(i)
        # 部分集合tとその補集合に分かれる場合
        # 全体集合sから始めて、「1を引く」「sと論理積をとる」を繰り返すことで
        # すべての部分集合を列挙できる
        first = [True] * m
        t = (s - 1) & s
        while first[t] and t > 0:
            value_div = dp[t] + dp[s - t]
            if value_div > value: value = value_div
            first[s - t] = False
            t = (t - 1) & s
        dp[s]=value
    print(dp[m-1])

main()


Fixed submission:
def max_ten(s):
    if memo[s]!="e":
        return memo[s]
    ten = 0
    # 分けない場合の点数
    for ai, ar in enumerate(a[:-1]):
        if s >> ai & 1:
            ten += sum(ar[j] * (s >> j & 1) for j in range(1 + ai, n))
    # 分ける場合の点数
    bubun = (s - 1) & s
    while bubun > 0:
        kari = max_ten(bubun) + max_ten(bubun ^ s)
        if kari > ten:
            ten = kari
        bubun = (bubun - 1) & s
    memo[s] = ten
    return ten


n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
s = (1 << n) - 1
memo = ["e"] * (1 << n)
print(max_ten(s))

Buggy python submission (verdict: Time Limit Exceeded):
def max_ten(s):
    if memo[s]!="e":
        return memo[s]
    ten = 0
    # 分けない場合の点数
    for ai, ar in enumerate(a[:-1]):
        if s >> ai & 1:
            ten += sum(ar[j] * (s >> j & 1) for j in range(1 + ai, n))
    # 分ける場合の点数
    bubun = (s - 1) & s
    while bubun > 0:
        kari = max_ten(bubun) + max_ten(bubun ^ s)
        if kari > ten:
            ten = kari
        bubun = (bubun - 1) & s
    memo[s] = ten
    return ten


n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
s = (1 << n) - 1
memo = ["e"] * (1 << n)
print(max_ten(s))


Fixed submission:
def max_ten(s):
    if memo[s]!="e":
        return memo[s]
    ten = 0
    # 分けない場合の点数
    for ai, ar in enumerate(a[:-1]):
        if s >> ai & 1:
            ten += sum(ar[j] * (s >> j & 1) for j in range(1 + ai, n))
    # 分ける場合の点数
    bubun = (s - 1) & s
    while bubun > 0:
        kari = max_ten(bubun) + max_ten(bubun ^ s)
        if kari > ten:
            ten = kari
        bubun = (bubun - 1) & s
    memo[s] = ten
    return ten


n = int(input())
a = [list(map(int, input().split())) for _ in range(n)]
s = (1 << n) - 1
memo = ["e"] * (1 << n)
print(max_ten(s))