Problem:


Score: 500 points

Problem Statement

New AtCoder City has an infinite grid of streets, as follows:

At the center of the city stands a clock tower. Let (0, 0) be the coordinates of this point.

A straight street, which we will call East-West Main Street, runs east-west and passes the clock tower. It corresponds to the x-axis in the two-dimensional coordinate plane.

There are also other infinitely many streets parallel to East-West Main Street, with a distance of 1 between them. They correspond to the lines \ldots, y = -2, y = -1, y = 1, y = 2, \ldots in the two-dimensional coordinate plane.

A straight street, which we will call North-South Main Street, runs north-south and passes the clock tower. It corresponds to the y-axis in the two-dimensional coordinate plane.

There are also other infinitely many streets parallel to North-South Main Street, with a distance of 1 between them. They correspond to the lines \ldots, x = -2, x = -1, x = 1, x = 2, \ldots in the two-dimensional coordinate plane.

There are N residential areas in New AtCoder City. The i-th area is located at the intersection with the coordinates (X_i, Y_i) and has a population of P_i. Each citizen in the city lives in one of these areas.

The city currently has only two railroads, stretching infinitely, one along East-West Main Street and the other along North-South Main Street.

M-kun, the mayor, thinks that they are not enough for the commuters, so he decides to choose K streets and build a railroad stretching infinitely along each of those streets.

Let the walking distance of each citizen be the distance from his/her residential area to the nearest railroad.

M-kun wants to build railroads so that the sum of the walking distances of all citizens, S, is minimized.

For each K = 0, 1, 2, \dots, N, what is the minimum possible value of S after building railroads?

Constraints

1 \leq N \leq 15

-10 \ 000 \leq X_i \leq 10 \ 000

-10 \ 000 \leq Y_i \leq 10 \ 000

1 \leq P_i \leq 1 \ 000 \ 000

The locations of the N residential areas, (X_i, Y_i), are all distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
X_1 Y_1 P_1
X_2 Y_2 P_2
 :  :  :
X_N Y_N P_N

Output

Print the answer in N+1 lines.

The i-th line (i = 1, \ldots, N+1) should contain the minimum possible value of S after building railroads for the case K = i-1.

Sample Input 1

3
1 2 300
3 3 600
1 4 800

Sample Output 1

2900
900
0
0

When K = 0, the residents of Area 1, 2, and 3 have to walk the distances of 1, 3, and 1, respectively, to reach a railroad.

Thus, the sum of the walking distances of all citizens, S, is 1 \times 300 + 3 \times 600 + 1 \times 800 = 2900.

When K = 1, if we build a railroad along the street corresponding to the line y = 4 in the coordinate plane, the walking distances of the citizens of Area 1, 2, and 3 become 1, 1, and 0, respectively.

Then, S = 1 \times 300 + 1 \times 600 + 0 \times 800 = 900.

We have many other options for where we build the railroad, but none of them makes S less than 900.

When K = 2, if we build a railroad along the street corresponding to the lines x = 1 and x = 3 in the coordinate plane, all citizens can reach a railroad with the walking distance of 0, so S = 0. We can also have S = 0 when K = 3.

The figure below shows the optimal way to build railroads for the cases K = 0, 1, 2.

The street painted blue represents the roads along which we build railroads.

Sample Input 2

5
3 5 400
5 3 700
5 5 1000
5 7 700
7 5 400

Sample Output 2

13800
1600
0
0
0
0

The figure below shows the optimal way to build railroads for the cases K = 1, 2.

Sample Input 3

6
2 5 1000
5 2 1100
5 5 1700
-2 -5 900
-5 -2 600
-5 -5 2200

Sample Output 3

26700
13900
3200
1200
0
0
0

The figure below shows the optimal way to build railroads for the case K = 3.

Sample Input 4

8
2 2 286017
3 1 262355
2 -2 213815
1 -3 224435
-2 -2 136860
-3 -1 239338
-2 2 217647
-1 3 141903

Sample Output 4

2576709
1569381
868031
605676
366338
141903
0
0
0

The figure below shows the optimal way to build railroads for the case K = 4.



Sample input:
3
1 2 300
3 3 600
1 4 800


Sample output:
2900
900
0
0

Submission status: Time Limit Exceeded

Solution code:
# coding: utf-8
import sys
#from operator import itemgetter
sysread = sys.stdin.buffer.readline
read = sys.stdin.buffer.read
#from heapq import heappop, heappush
from collections import defaultdict
sys.setrecursionlimit(10**7)
import math
from itertools import product, accumulate, combinations, product
#import bisect# lower_bound etc
import numpy as np
#from copy import deepcopy
#from collections import deque


def run():
    N = int(sysread())
    INF = 1 << 50
    X, Y, P = [-1], [-1], [-1]
    ans = [INF] * (N+1)

    INF = 1 << 50
    hline = [0]
    vline = [0]
    dist_arr = np.zeros([2 * (N+1), N+1], dtype= np.int64)
    for i in range(1, N+1):
        x,y,p = map(int, sysread().split())
        X.append(x)
        Y.append(y)
        P.append(p)
        dist_arr[0, i] = abs(x) * p
        dist_arr[N+1, i] = abs(y) * p



    for i in range(1, N+1):
        v = X[i]
        h = Y[i]
        for k in range(1, N+1):
            # vertical
            dist_arr[i, k] = abs(v-X[k]) * P[k]
            dist_arr[N+1+i, k] = abs(h-Y[k]) * P[k]
    dist_arr = dist_arr[:, 1:]
    #print(dist_arr)

    for vals in product((0,1,2), repeat = N):
        xlines = set()
        ylines = set()
        idx = [0, N+1]
        for i, val in enumerate(vals, 1):
            if val == 0:
                continue
            elif val == 1:
                # vertical
                xlines.add(X[i])
                idx.append(i)
            else:
                ylines.add(Y[i])
                idx.append(N+1+i)
        k = len(xlines) + len(ylines)
        idx = np.array(idx)

        D = dist_arr[idx, :].min(axis = 0).sum()

        ans[k] = min(ans[k], D)

    for a in ans:
        print(a)





if __name__ == "__main__":
    run()

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
xyp = [list(map(int, input().split())) for _ in range(N)]

ans = {}
x_cnt = [0] * 2**N
y_cnt = [0] * 2**N
dist_x = [[0] * N for _ in range(2**N)]
dist_y = [[0] * N for _ in range(2**N)]
for i in range(2**N):
    flg = [0] * N
    tmp_i = i
    for j in range(N):
        flg[j] = tmp_i%2
        tmp_i //= 2

    x_line = [0]
    y_line = [0]
    for j in range(N):
        if flg[j] == 1:
            x_line.append(xyp[j][0])
            y_line.append(xyp[j][1])
    for j in range(N):
        x_cnt[i] = len(list(set(x_line))) - 1
        y_cnt[i] = len(list(set(y_line))) - 1
        dist_x[i][j] = min([abs(x-xyp[j][0])*xyp[j][2] for x in x_line])
        dist_y[i][j] = min([abs(y-xyp[j][1])*xyp[j][2] for y in y_line])
        
for i in range(3**N):
    x_idx = 0
    y_idx = 0
    for j in range(N):
        if i % 3 == 0:
            x_idx += 2**j
        elif i % 3 == 1:
            y_idx += 2**j
        i //= 3
    
    k = x_cnt[x_idx] + y_cnt[y_idx]
    dist = 0
    for j in range(N):
        dist += min(dist_x[x_idx][j], dist_y[y_idx][j])
    if ans.get(k) is not None:
        ans[k] = min(ans[k], dist)
    else:
        ans[k] = dist
    
for i in range(N+1):
    print(ans[i])

Submission status: Time Limit Exceeded

Solution code:
import numpy as np
from numba import njit
import sys

read = sys.stdin.buffer.read


@njit
def solve(inp):
    INF = 10 ** 18

    n = inp[0]
    x = inp[1::3]
    y = inp[2::3]
    p = inp[3::3]

    ver = np.empty((1 << n, n), np.int64)
    ver[0] = np.abs(x) * p

    for i in range(n):
        bt = 1 << i
        ver[bt:2 * bt] = np.minimum(ver[:bt], np.abs(x - x[i]) * p)

    hor = np.empty((1 << n, n), np.int64)
    hor[0] = np.abs(y) * p

    for i in range(n):
        bt = 1 << i
        hor[bt:2 * bt] = np.minimum(hor[:bt], np.abs(y - y[i]) * p)

    ans = [INF] * (n + 1)
    for i in range(3 ** n):
        vi = 0
        hi = 0
        cnt = 0
        pow2 = 1
        pow3 = i
        while pow3:
            r = pow3 % 3
            pow3 //= 3
            if r == 1:
                vi += pow2
                cnt += 1
            elif r == 2:
                hi += pow2
                cnt += 1

            pow2 *= 2

        score = np.minimum(ver[vi], hor[hi]).sum()
        ans[cnt] = min(ans[cnt], score)

    return ans


inp = np.array(read().split(), np.int64)
ans = solve(inp)
print(*ans, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from numba import njit
import numpy as np
INF = 10**18

@njit('(i8, i8[:,:])')
def solve(N, XYP):
    X = XYP[:, 0]
    Y = XYP[:, 1]

    def calcCost(sign, A):
        ret = np.ones((1 << N, N), dtype=np.int64) * INF
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i in range(N):
                xyp = XYP[i]
                cost = abs(xyp[sign])
                for z in useA:
                    cost = min(cost, abs(xyp[sign] - z))
                ret[state][i] = cost * xyp[2]
        return ret

    costX = calcCost(0, X)
    costY = calcCost(1, Y)
    ans = np.ones(N + 1, dtype=np.int64) * INF

    for state in range(pow(3, N)):
        stateX = 0
        stateY = 0
        M = N
        for _ in range(N):
            state, r = divmod(state, 3)
            stateX <<= 1
            stateY <<= 1
            if r == 0: M -= 1
            if r == 1: stateX |= 1
            if r == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = np.minimum(cx, cy).sum()
        ans[M] = min(ans[M], cost)

    for a in ans:
        print(a)

def sol():
    N = int(input())
    XYP = np.asarray([list(map(int, input().split())) for _ in range(N)])
    solve(N, XYP)

sol()

Submission status: Time Limit Exceeded

Solution code:
def main():
    from sys import setrecursionlimit, stdin, stderr
    from os import environ
    from collections import defaultdict, deque, Counter
    from math import ceil, floor
    from itertools import accumulate, combinations, combinations_with_replacement, product
    setrecursionlimit(10**6)
    dbg = (lambda *something: stderr.write("\033[92m{}\033[0m".format(str(something)+'\n'))) if 'TERM_PROGRAM' in environ else lambda *x: 0
    input = lambda: stdin.readline().rstrip()
    LMIIS = lambda: list(map(int,input().split()))
    II = lambda: int(input())
    P = 10**9+7
    INF = 10**12

    N = II()
    positions = deque()
    for i in range(N):
        positions.append(LMIIS())
    
    #縦、横の最短距離
    v = []
    h = []
    for i in range(2**N):
        v.append([INF]*N)
        h.append([INF]*N)
    for i in range(2**N):
        v_lines = deque([0])
        h_lines = deque([0])
        for j in range(N):
            if 2 ** j & i:
                v_lines.append(positions[j][0])
                h_lines.append(positions[j][1])
        for j,(x,y,p) in enumerate(positions):
            min_x = INF
            min_y = INF
            for x_c in v_lines:
                min_x = min(min_x, abs(x_c - x)*p)
            for y_c in h_lines:
                min_y = min(min_y, abs(y_c - y)*p)
            v[i][j] = min_x
            h[i][j] = min_y

    ans = [INF]*(N+1)
    #for pattern in product(range(3),repeat=N):
    n_bit_mask = (1<<N)-1
    for pattern_v in range(2**N):
        pattern_h = h_mask = n_bit_mask^pattern_v
        pattern_h += 1
        while pattern_h > 0:
            pattern_h -= 1
            pattern_h &= h_mask
            pattern = pattern_h|pattern_v
            key = 0
            for i in range(N):
                if 2**i & pattern:
                    key += 1


        # for p in pattern:
        #     pattern_v *= 2
        #     pattern_h *= 2
        #     if p == 1:
        #         pattern_v += 1
        #     elif p == 2:
        #         pattern_h += 1
        #     else:a
        #         key -= 1
            sum_diff = 0
            for i in range(N):
                sum_diff += min(v[pattern_v][i],h[pattern_h][i])

            ans[key] = min(ans[key], sum_diff)
    print('\n'.join(map(str,ans)))





            



    

    



    
main()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from numba import njit
import numpy as np
INF = 10**18

@njit('(i8, i8[:,:], i8[:,:])')
def solve(N, costX, costY):
    ans = np.ones(N + 1, dtype=np.int64) * INF

    for state in range(pow(3, N)):
        stateX = 0
        stateY = 0
        M = N
        for _ in range(N):
            state, r = divmod(state, 3)
            stateX <<= 1
            stateY <<= 1
            if r == 0: M -= 1
            if r == 1: stateX |= 1
            if r == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = np.minimum(cx, cy).sum()
        ans[M] = min(ans[M], cost)

    for a in ans:
        print(a)

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = np.ones((1 << N, N), dtype=np.int64) * INF
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    solve(N, costX, costY)

sol()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from numba import njit
import numpy as np
INF = 10**18

@njit
def solve(N, costX, costY):
    ans = np.ones(N + 1, dtype=np.int64) * INF

    for state in range(pow(3, N)):
        stateX = 0
        stateY = 0
        M = N
        for _ in range(N):
            state, r = divmod(state, 3)
            stateX <<= 1
            stateY <<= 1
            if r == 0: M -= 1
            if r == 1: stateX |= 1
            if r == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = np.minimum(cx, cy).sum()
        ans[M] = min(ans[M], cost)

    return ans

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = np.ones((1 << N, N), dtype=np.int64) * INF
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    ans = solve(N, costX, costY)
    print(*ans, sep='\n')

sol()

Submission status: Time Limit Exceeded

Solution code:
INF = float("inf")

N, *XYP = map(int, open(0).read().split())
XYP = list(zip(*[iter(XYP)] * 3))

def solve(XP):
    M = len(XP)
    XP.sort()

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

    for i, (x, p) in enumerate(XP):
        dp[i + 1][0] = dp[i][0] + abs(x) * p

    for l, dpl in enumerate(dp[:M]):
        for r in range(l + 1, M + 1):
            val = INF
            for lx, _ in XP[l:r]:
                cur = 0
                for x, p in XP[l:r]:
                    cur += p * min(abs(x - lx), abs(x))
                val = min(val, cur)

            for i in range(1, M + 1):
                dp[r][i] = min(
                    dp[r][i],
                    val + dpl[i - 1]
                )

    res = [INF] * (N + 1)
    res[:M + 1] = dp[M]
    return res


A = [INF] * (N + 1)
for state in range(1 << N):
    XP, YP = [], []
    for i, (x, y, p) in enumerate(XYP):
        if (state >> i) & 1:
            XP.append((x, p))
        else:
            YP.append((y, p))

    X, Y = solve(XP), solve(YP)
    for i in range(N + 1):
        for j in range(N + 1 - i):
            A[i + j] = min(A[i + j], X[i] + Y[j])

for a in A:
    print(a)

Submission status: Time Limit Exceeded

Solution code:
N = int(input())

A = [tuple(map(int,input().split())) for _ in range(N)]

#準備：S_の外延表記sを求める
def settify(S):
  s = []
  i = 0
  while S > 0:
    if (S & 1):  
      s.append(i)
    S = S >> 1
    i += 1
  return s

Sets = [settify(S_) for S_ in range(2**N)]
b = [2 ** i for i in range(N)] #2べき

def DP_solve(S, A, l, L): #l=0:x, l=1:y, L:最大本数
  if S == 0:
    return [0 for _ in range(L+1)]
  s = Sets[S]
  n = len(s)
  B = [(A[i][l],A[i][2]) for i in s]#位置,コスト(人口)
  B.sort()
  Q = [[0 for _ in range(n)] for _ in range(n)]#準備用
  for j in range(n):
    for k in range(j):#k < j
      Q[k][j] = sum([min(abs(B[l][0]),abs(B[l][0]-B[k][0]),abs(B[l][0]-B[j][0]))*B[l][1] for l in range(k+1,j)])
  DP = [[-1 for _ in range(n)] for _ in range(L+1)]
  #print(DP)
  for j in range(n):
    DP[1][j] = sum([min(abs(B[l][0]),abs(B[l][0]-B[j][0]))*B[l][1] for l in range(j)]) #i本目を置いて、最後がj番目の集落
  for i in range(2,L+1):
    DP[i][0] = DP[i-1][0]
    for j in range(1,n):
      DP[i][j] = min([DP[i-1][k]+Q[k][j] for k in range(j)])
      #i本目を置いて、最後がj番目の集落
      
  return [min([DP[i][j]+sum([min(abs(B[l][0]),abs(B[l][0]-B[j][0]))*B[l][1] for l in range(j+1,n)]) for j in range(n)]) if i >= 1 else sum([abs(B[l][0])*B[l][1] for l in range(n)]) for i in range(L+1)]

#1次元へ帰着
X = [DP_solve(S_,A,0, N) for S_ in range(2**N)]
Y = [DP_solve(S_,A,1, N) for S_ in range(2**N)]
#print(X)  
for k in range(N+1):#合計k本(大通り以外)
  ans = 10**20
  for S_ in range(2**N):#X側に集合S_が割り当てられる
    for i in range(k+1):#x軸平行にi本   
      #print(ans, X[S_][i] + Y[2**N-1-S_][k-i])
      ans = min(ans, X[S_][i] + Y[2**N-1-S_][k-i])
  print(ans)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from numba import njit
import numpy as np
INF = 10**18

@njit(cache=True)
def solve(N, costX, costY):
    ans = [INF] * (N + 1)

    for state in range(pow(3, N)):
        stateX = 0
        stateY = 0
        M = N
        for _ in range(N):
            state, r = divmod(state, 3)
            stateX <<= 1
            stateY <<= 1
            if r == 0: M -= 1
            if r == 1: stateX |= 1
            if r == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = np.minimum(cx, cy).sum()
        ans[M] = min(ans[M], cost)

    return ans

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = np.ones((1 << N, N), dtype=np.int64) * INF
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    ans = solve(N, costX, costY)
    print(*ans, sep='\n')

sol()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from numba import njit
import numpy as np
INF = 10**18

# @njit
def solve(N, costX, costY):
    ans = [INF] * (N + 1)

    for state in range(pow(3, N)):
        stateX = 0
        stateY = 0
        M = N
        for _ in range(N):
            state, r = divmod(state, 3)
            stateX <<= 1
            stateY <<= 1
            if r == 0: M -= 1
            if r == 1: stateX |= 1
            if r == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = np.minimum(cx, cy).sum()
        ans[M] = min(ans[M], cost)

    return ans

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = np.ones((1 << N, N), dtype=np.int64) * INF
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    ans = solve(N, costX, costY)
    print(*ans, sep='\n')

sol()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from numba import njit
import numpy as np
INF = 10**18

@njit
def solve(N, costX, costY):
    ans = [INF] * (N + 1)

    for state in range(pow(3, N)):
        stateX = 0
        stateY = 0
        M = N
        for _ in range(N):
            state, r = divmod(state, 3)
            stateX <<= 1
            stateY <<= 1
            if r == 0: M -= 1
            if r == 1: stateX |= 1
            if r == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = np.minimum(cx, cy).sum()
        ans[M] = min(ans[M], cost)

    return ans

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = np.ones((1 << N, N), dtype=np.int64) * INF
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    ans = solve(N, costX, costY)
    print(*ans, sep='\n')

sol()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from numba import njit
import numpy as np
INF = 10**18

@njit
def solve(N, costX, costY):
    ans = [INF] * (N + 1)

    for state in range(pow(3, N)):
        stateX = 0
        stateY = 0
        M = N
        for _ in range(N):
            state, r = divmod(state, 3)
            stateX <<= 1
            stateY <<= 1
            if r == 0: M -= 1
            if r == 1: stateX |= 1
            if r == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = 0
        for i in range(N):
            cost += min(cx[i], cy[i])
            if cost >= ans[M]:
                break
        else:
            ans[M] = cost

    return ans

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = np.ones((1 << N, N), dtype=np.int64) * INF
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    ans = solve(N, costX, costY)
    print(*ans, sep='\n')

sol()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from itertools import product
from random import sample
INF = 10**18

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = [[INF] * N for _ in range(1 << N)]
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    ans = [INF] * (N + 1)
    for state in product((0, 1, 2), repeat=N):
        stateX = 0
        stateY = 0
        M = N
        for s in state:
            stateX <<= 1
            stateY <<= 1
            if s == 0: M -= 1
            if s == 1: stateX |= 1
            if s == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = 0
        for i in sample(range(N), k=N):
            cost += min(cx[i], cy[i])
            if cost >= ans[M]:
                break
        else:
            ans[M] = cost

    print(*ans, sep='\n')

sol()

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline
import numpy as np
from numba import njit


def read():
    N = int(input().strip())
    XYP = np.empty((N, 3), dtype=np.int32)
    for i in range(N):
        XYP[i] = np.fromstring(input().strip(), sep=" ")
    return N, XYP


@njit
def solve(N, XYP, INF=10**18):
    ans = np.full(N+1, INF, dtype=np.int64)
    vcost = np.zeros((N, 2**N), dtype=np.int32)
    hcost = np.zeros((N, 2**N), dtype=np.int32)

    # check 2**N pairs
    for intptn in range(2**N):
        for i in range(N):
            xi, yi, pi = XYP[i]
            v = abs(xi)
            h = abs(yi)
            for j in range(N):
                xj, yj, pj = XYP[j]
                if (intptn >> j) & 1 == 1:
                    v = min(v, abs(xj-xi))
                    h = min(h, abs(yj-yi))
            vcost[i, intptn] += v
            hcost[i, intptn] += h

    # check 3**N pairs
    for intptn in range(3**N):
        # split into two 2**N pairs
        p, intvptn, inthptn = intptn, 0, 0
        u = 0
        for i in range(N):
            if p % 3 == 1:
                intvptn += 1 << (N-i-1)
                u += 1
            elif p % 3 == 2:
                inthptn += 1 << (N-i-1)
                u += 1
            p //= 3
        s = 0
        for i in range(N):
            s += min(vcost[i, intvptn], hcost[i, inthptn]) * XYP[i, 2]
        ans[u] = min(ans[u], s)
    
    return ans


if __name__ == '__main__':
    inputs = read()
    ans = solve(*inputs)
    for a in ans:
        print(a)

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
X = []
Y = []
P = []

for i in range(N):
    x, y, p = list(map(int, input().split()))
    X.append(x)
    Y.append(y)
    P.append(p)

pre_x = [[abs(X[j]) for j in range(N)] for i in range(1 << N)]
pre_y = [[abs(Y[j]) for j in range(N)] for i in range(1 << N)]

for i in range(1 << N):
    for j in range(N):
        mx = abs(X[j])
        my = abs(Y[j])
        for k in range(N):
            if (i >> k) & 1:
                mx = min(mx, abs(X[k]-X[j]))
                my = min(my, abs(Y[k]-Y[j]))
        pre_x[i][j] = mx
        pre_y[i][j] = my

ans = [1 << 63 for i in range(N+1)]
for i in range(1 << N):
    cnt = 0
    for j in range(N):
        if (i >> j) & 1:
            cnt += 1
    for j in reversed(range(0, i+1)):
        j = j & i
        cost = 0
        for k in range(N):
            if not ((i >> k) & 1):
                cost += min(pre_x[j][k], pre_y[i-j][k]) * P[k]
        ans[cnt] = min(ans[cnt], cost)

print(*ans, sep="\n")

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.readline
from itertools import product


def read():
    N = int(input().strip())
    XYP = []
    for i in range(N):
        x, y, p = map(int, input().strip().split())
        XYP.append((x, y, p))
    return N, XYP


def solve(N, XYP, INF=10**18):
    ans = [INF for i in range(N+1)]
    vcost = [[0 for j in range(2**N)] for i in range(N)]
    hcost = [[0 for j in range(2**N)] for i in range(N)]

    # check 2**N pairs
    for intptn in range(2**N):
        for i, (xi, yi, pi) in enumerate(XYP):
            v = abs(xi)
            h = abs(yi)
            for j, (xj, yj, pj) in enumerate(XYP):
                if (intptn >> j) & 1 == 1:
                    v = min(v, abs(xj-xi))
                    h = min(h, abs(yj-yi))
            vcost[i][intptn] += v * pi
            hcost[i][intptn] += h * pi

    # check 3**N pairs
    for ptn in product(range(3), repeat=N):
        # split into two 2**N pairs
        intvptn = sum([1<<(N-i-1) for i in range(N) if ptn[i]==1])
        inthptn = sum([1<<(N-i-1) for i in range(N) if ptn[i]==2])
        s = 0
        for i in range(N):
            s += min(vcost[i][intvptn], hcost[i][inthptn])
        u = sum([t>0 for t in ptn])
        ans[u] = min(ans[u], s)

    for u in range(N+1):
        print(ans[u])


if __name__ == '__main__':
    inputs = read()
    solve(*inputs)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = sys.stdin.buffer.readline
from itertools import product
INF = 10**18

def sol():
    N = int(input())
    XYP = [tuple(map(int, input().split())) for _ in range(N)]
    XYP.sort(key=lambda xyp: max(abs(xyp[0]), abs(xyp[1])) * xyp[2], reverse=False)

    X = [x for x, _, _ in XYP]
    Y = [y for _, y, _ in XYP]

    def calcCost(AP, A):
        ret = [[INF] * N for _ in range(1 << N)]
        for state in range(1 << N):
            useA = [a for i, a in enumerate(A) if (state & (1 << i)) != 0]
            for i, (a, p) in enumerate(AP):
                cost = abs(a)
                for z in useA:
                    cost = min(cost, abs(a - z))
                ret[state][i] = cost * p
        return ret

    costX = calcCost([(x, p) for x, _, p in XYP], X)
    costY = calcCost([(y, p) for _, y, p in XYP], Y)

    ans = [INF] * (N + 1)
    for state in product((0, 1, 2), repeat=N):
        stateX = 0
        stateY = 0
        M = N
        for s in state:
            stateX <<= 1
            stateY <<= 1
            if s == 0: M -= 1
            if s == 1: stateX |= 1
            if s == 2: stateY |= 1

        cx, cy = costX[stateX], costY[stateY]
        cost = 0
        for i in range(N):
            cost += min(cx[i], cy[i])
            if cost >= ans[M]:
                break
        else:
            ans[M] = cost

    print(*ans, sep='\n')

sol()