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:
import math, itertools

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

streets = [(x, y) for x, y, _ in XYP]
distance_x = [[math.inf for _ in range(N)] for _ in range(2**N)]
distance_y = [[math.inf for _ in range(N)] for _ in range(2**N)]
for i in range(2**N):
    for j in range(N):
        x, y, p = XYP[j]
        dx, dy = abs(x), abs(y)
        for k in range(N):
            if i>>k&1:
                dx = min(dx, abs(x - XYP[k][0]))
                dy = min(dy, abs(y - XYP[k][1]))
        distance_x[i][j] = dx * p
        distance_y[i][j] = dy * p


def S(x_bit, y_bit):
    res = 0
    xs, ys = distance_x[x_bit], distance_y[y_bit]
    for i in range(N):
        res += min(xs[i], ys[i])
    return res


ans = [math.inf]*N
for i in range(3**N):
    x_bit, y_bit, cnt = 0, 0, 0
    for j in range(N):
        b = (i//(3**j)) % 3
        if b == 1:
            x_bit += 2**j
            cnt += 1
        if b == 2:
            y_bit += 2**j
            cnt += 1
    if cnt >= N:
        continue
    ans[cnt] = min(ans[cnt], S(x_bit, y_bit))
for i in range(N):
    print(ans[i])
print(0)

Submission status: Time Limit Exceeded

Solution code:
import math, itertools

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

streets = [(x, y) for x, y, _ in XYP]
distance_x = [[math.inf for _ in range(N)] for _ in range(2**N)]
distance_y = [[math.inf for _ in range(N)] for _ in range(2**N)]
for i in range(2**N):
    for j in range(N):
        x, y, p = XYP[j]
        dx, dy = abs(x), abs(y)
        for k in range(N):
            if i>>k&1:
                dx = min(dx, abs(x - XYP[k][0]))
                dy = min(dy, abs(y - XYP[k][1]))
        distance_x[i][j] = dx * p
        distance_y[i][j] = dy * p


def S(x_bit, y_bit):
    res = 0
    for i in range(N):
        res += min(distance_x[x_bit][i], distance_y[y_bit][i])
    return res


ans = [math.inf]*N
for i in range(3**N):
    x_bit, y_bit, cnt = 0, 0, 0
    for j in range(N):
        b = (i//(3**j)) % 3
        if b == 1:
            x_bit += 2**j
            cnt += 1
        if b == 2:
            y_bit += 2**j
            cnt += 1
    if cnt >= N:
        continue
    ans[cnt] = min(ans[cnt], S(x_bit, y_bit))
for i in range(N):
    print(ans[i])
print(0)

Submission status: Time Limit Exceeded

Solution code:
import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))
write = lambda x: sys.stdout.write(x+"\n")


n = int(input())
xyp = [None]*n
cost = [None]*n
for i in range(n):
    x,y,p = tuple(map(int, input().split()))
    xyp[i] = (x,y,p,i)
    cost[i] = min(abs(xyp[i][0]), abs(xyp[i][1]))
xyp0 = sorted(xyp, key=lambda x: x[0])
xyp1 = sorted(xyp, key=lambda x: x[1])

def ccost(cost):
    return sum(cost[i]*xyp[i][2] for i in range(n))
ans = [float("inf")]*(n+1)
def ccost(xs, ys):
    xmins = [float("inf")] * n
    ymins = [float("inf")] * n
    xs.sort()
    ys.sort()
    j = 0
    for i in range(n):
        x,y,p,ind = xyp0[i]
        xm = abs(x-xs[j])
        while j+1<len(xs) and xm>abs(x-xs[j+1]):
            j += 1
            xm = abs(x-xs[j])
        xmins[ind] = xm
    j = 0
    for i in range(n):
        x,y,p,ind = xyp1[i]
        ym = abs(y-ys[j])
        while j+1<len(ys) and ym>abs(y-ys[j+1]):
            j += 1
            ym = abs(y-ys[j])
        ymins[ind] = ym
    return sum(item[2]*min(xx,yy) for item,xx,yy in zip(xyp, xmins, ymins))
from itertools import product
for b in product(*[range(3) for _ in range(n)]):
    xs = [0]
    ys = [0]
    num = 0
    for i in range(n):
        if b[i]==1:
            xs.append(xyp[i][0])
            num += 1
        elif b[i]==2:
            ys.append(xyp[i][1])
            num += 1
    cc = ccost(xs, ys)
#     print(b,xs,ys,cc,num)
    ans[num] = min(ans[num], cc)
write("\n".join(map(str, ans)))

Submission status: Time Limit Exceeded

Solution code:
import datetime
import itertools
start=datetime.datetime.now()
N=int(input())
X=[0 for i in range(N)]
Y=[0 for i in range(N)]
P=[0 for i in range(N)]
for i in range(N):
    X[i],Y[i],P[i]=map(int,input().split())
INF=10**15
ans=[INF for i in range(N+1)]
#print(datetime.datetime.now()-start)
start=datetime.datetime.now()
NS=[[0 for j in range(N)] for i in range(2**N)]
WE=[[0 for j in range(N)] for i in range(2**N)]
#print(datetime.datetime.now()-start)
start=datetime.datetime.now()
for num in range(2**N):
    for i in range(N):
        tmp=abs(Y[i])
        for j in range(N):
            if num&(1<<j):
                tmp=min(tmp,abs(X[j]-X[i]))
        NS[num][i]=tmp*P[i]
#print(datetime.datetime.now()-start)
start=datetime.datetime.now()
for num in range(2**N):
    for i in range(N):
        tmp=abs(X[i])
        for j in range(N):
            if num&(1<<j):
                tmp=min(tmp,abs(Y[j]-Y[i]))
        WE[num][i]=tmp*P[i]
#print(datetime.datetime.now()-start)
start=datetime.datetime.now()
for num in range(3**N):
	numtmp=num
	x=set()
	y=set()
	A=0
	B=0
	for i in range(N):
	    n=numtmp%3
	    if n==0:
	        x.add(X[i])
	        A^=(1<<i)
	    if n==1:
	        y.add(Y[i])
	        B^=(1<<i)
	    numtmp//=3
	K=len(x)+len(y)
	tmp=0
	for i in range(N):
	    tmp+=min(NS[A][i],WE[B][i])
	ans[K]=min(ans[K],tmp)
#print(datetime.datetime.now()-start)
start=datetime.datetime.now()
for line in ans:
    print(line)

Submission status: Time Limit Exceeded

Solution code:
def score(CITIES, lines, lower_bound, city_lines, city_scores):
    s = 0
    for cityid in range(len(CITIES)):
        x = CITIES[cityid][0]
        y = CITIES[cityid][1]
        p = CITIES[cityid][2]

        for ctl in city_lines[cityid]:
            if ctl in lines:
                s += city_scores[cityid][ctl]
                break
        if s >= lower_bound:
            return lower_bound
    return s

def recursive_score(K, CITIES, candidate_lines, selected, max_selected, lower_bound, city_lines, city_scores):
    if K == len(CITIES):
        return 0

    if len(selected) == K:
        lines = [(0, "H"), (0, "V")]
        for s in selected:
            lines.append(candidate_lines[s])
        return score(CITIES, lines, lower_bound, city_lines, city_scores)

    min_score = lower_bound
    for i in range(len(candidate_lines)):
        if i <= max_selected:
            continue
        max_selected = i
        sel = selected + [i]
        s = recursive_score(K, CITIES, candidate_lines, sel, max_selected, min_score, city_lines, city_scores)
        if s == 0:
            return 0
        min_score = min(min_score, s)
    return min_score

def main():
    N = int(input())
    CITIES = []

    for i in range(N):
        # x=c[0]
        # y=c[1]
        # p=c[2]
        c = [int(_x) for _x in input().split()]
        CITIES.append(c)

    candidate_lines_org = []
    for i in range(N):
        candidate_lines_org.append((CITIES[i][1], "H"))  # y座標が同じで横線
        candidate_lines_org.append((CITIES[i][0], "V"))  # x座標が同じで縦線

    # 2つ以上の都市に乗る線は優先度を高くしつつ、一回のみカウント
    duplicate_lines = []
    single_lines = []
    for i in range(len(candidate_lines_org)):
        dup = False
        for j in range(len(candidate_lines_org)):
            if j <= i:
                continue
            if candidate_lines_org[i] == candidate_lines_org[j]:
                dup = True
                duplicate_lines.append(candidate_lines_org[i])
                break
        if not dup:
            single_lines.append(candidate_lines_org[i])
    candidate_lines = duplicate_lines + single_lines

    # 線-都市ペアでのscoreを事前計算
    score_target_lines = candidate_lines + [(0, "H"), (0, "V")]
    city_lines = {}
    city_scores = {}
    for i in range(N):
        cityid_score = []

        x = CITIES[i][0]
        y = CITIES[i][1]
        p = CITIES[i][2]
        for l in score_target_lines:
            if l[1] == "H":
                dist = abs(y-l[0])
            else:
                dist = abs(x-l[0])
            cityid_score.append((dist*p, l))

        city_lines[i] = []
        for score, line in sorted(cityid_score, key=lambda x:x[0]):
            city_lines[i].append(line)
            if i not in city_scores:
                city_scores[i] = {}
            city_scores[i][line] = score

    lower_bound = 1000000000000
    for K in range(N+1):
        if lower_bound == 0:
            S = 0
        else:
            S = recursive_score(K, CITIES, candidate_lines, [], -1, lower_bound, city_lines, city_scores)
        print(S)
        lower_bound = S


main()

Submission status: Time Limit Exceeded

Solution code:
N=int(input())
L=[list(map(int,input().split())) for i in range(N)]
INF=10**18
t=[3**i for i in range(21)]
X=[[INF]*N for i in range(1<<N)]
Y=[[INF]*N for i in range(1<<N)]
def f(x):
  r=''
  for i in range(N):
    r+=str(x%3)
    x//=3
  return r

for i in range(1<<N):
  for j in range(N):
    X[i][j]=min(abs(L[j][0]),abs(L[j][1]))
    Y[i][j]=X[i][j]
    for k in range(N):
      if i&(1<<k):
        X[i][j]=min(X[i][j],abs(L[j][0]-L[k][0]))
        Y[i][j]=min(Y[i][j],abs(L[j][1]-L[k][1]))
    X[i][j]*=L[j][2]
    Y[i][j]*=L[j][2]
s=0
P=[INF]*(N+1)
Q=0
x,y=0,0
for i in range(t[N]):
  s=f(i)
  x,y=0,0
  for j in range(N):
    if s[j]=='1':
      x+=1<<j
    elif s[j]=='2':
      y+=1<<j
  P[len(s)-s.count('0')]=min(P[len(s)-s.count('0')],sum([min(X[x][j],Y[y][j]) for j in range(N)]))
print(*P,sep='\n')

Submission status: Time Limit Exceeded

Solution code:
# Fast IO (only use in integer input)

import os,io
input=io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

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

def abs(N):
    if N >= 0:
        return N
    else:
        return -N

minCost = [-1] * (N+1)

preCalRange = 1 << N

horizontalLineDistance = []
verticalLineDistance = []

for i in range(preCalRange):
    railRoad = bin(i)[2:]
    railRoad = '0' * (N - len(railRoad)) + railRoad
    horizontalLineDistance.append([])
    verticalLineDistance.append([])
    for j in range(N):
        horizontalLineDistance[i].append(min(abs(Resident[j][0]),abs(Resident[j][1])))
        verticalLineDistance[i].append(min(abs(Resident[j][0]),abs(Resident[j][1])))
        for k in range(N):
            if railRoad[k] == '1' and abs(Resident[j][0] - Resident[k][0]) < horizontalLineDistance[i][j]:
                horizontalLineDistance[i][j] = abs(Resident[j][0] - Resident[k][0])
            if railRoad[k] == '1' and abs(Resident[j][1] - Resident[k][1]) < verticalLineDistance[i][j]:
                verticalLineDistance[i][j] = abs(Resident[j][1] - Resident[k][1])

totalCases = 3 ** N

for i in range(totalCases):
    railRoad = []
    tmp = i
    for j in range(N):
        railRoad.append(tmp % 3)
        tmp //= 3
    horizontalCount = 0
    verticalCount = 0
    numNewRailroad = 0
    for j in range(N):
        if railRoad[j] == 1:
            numNewRailroad += 1
            horizontalCount += 1 << j
        if railRoad[j] == 2:
            verticalCount += 1 << j
            numNewRailroad += 1
    minDistance = []
    for j in range(N):
        minDistance.append(min(horizontalLineDistance[horizontalCount][j], verticalLineDistance[verticalCount][j]))

    cost = 0
    for j in range(N):
        cost += Resident[j][2] * minDistance[j]
    if minCost[numNewRailroad] == -1 or minCost[numNewRailroad] > cost:
        minCost[numNewRailroad] = cost
for elem in minCost:
    print(elem)

Submission status: Time Limit Exceeded

Solution code:
# Fast IO (only use in integer input)

# import os,io
# input=io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

from copy import copy

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

def abs(N):
    if N >= 0:
        return N
    else:
        return -N

minCost = [-1] * (N+1)

preCalRange = 1 << N

horizontalLineDistance = []
verticalLineDistance = []

for i in range(preCalRange):
    railRoad = bin(i)[2:]
    railRoad = '0' * (N - len(railRoad)) + railRoad
    horizontalLineDistance.append([])
    for j in range(N):
        horizontalLineDistance[i].append(min(abs(Resident[j][0]),abs(Resident[j][1])))
        for k in range(N):
            if railRoad[k] == '1' and abs(Resident[j][0] - Resident[k][0]) < horizontalLineDistance[i][j]:
                horizontalLineDistance[i][j] = abs(Resident[j][0] - Resident[k][0])
    verticalLineDistance.append([])
    for j in range(N):
        verticalLineDistance[i].append(min(abs(Resident[j][0]),abs(Resident[j][1])))
        for k in range(N):
            if railRoad[k] == '1' and abs(Resident[j][1] - Resident[k][1]) < verticalLineDistance[i][j]:
                verticalLineDistance[i][j] = abs(Resident[j][1] - Resident[k][1])

totalCases = 3 ** N

for i in range(totalCases):
    railRoad = []
    tmp = i
    for j in range(N):
        railRoad.append(tmp % 3)
        tmp //= 3
    horizontalCount = 0
    verticalCount = 0
    numNewRailroad = 0
    for j in range(N):
        if railRoad[j] == 1:
            numNewRailroad += 1
            horizontalCount += 1 << j
        if railRoad[j] == 2:
            verticalCount += 1 << j
            numNewRailroad += 1
    minDistance = []
    for j in range(N):
        minDistance.append(min(horizontalLineDistance[horizontalCount][j], verticalLineDistance[verticalCount][j]))

    cost = 0
    for j in range(N):
        cost += Resident[j][2] * minDistance[j]
    if minCost[numNewRailroad] == -1 or minCost[numNewRailroad] > cost:
        minCost[numNewRailroad] = cost
for elem in minCost:
    print(elem)

Submission status: Time Limit Exceeded

Solution code:
import itertools
N=int(input())
X=[0 for i in range(N)]
Y=[0 for i in range(N)]
P=[0 for i in range(N)]
for i in range(N):
    X[i],Y[i],P[i]=map(int,input().split())
INF=10**15
ans=[INF for i in range(N+1)]
NS=[[0 for j in range(N)] for i in range(2**N)]
WE=[[0 for j in range(N)] for i in range(2**N)]
for num in range(2**N):
    for i in range(N):
        tmp=abs(Y[i])
        for j in range(N):
            if num&(1<<j):
                tmp=min(tmp,abs(X[j]-X[i]))
        NS[num][i]=tmp
for num in range(2**N):
    for i in range(N):
        tmp=abs(X[i])
        for j in range(N):
            if num&(1<<j):
                tmp=min(tmp,abs(Y[j]-Y[i]))
        WE[num][i]=tmp
for seq in itertools.product(range(3),repeat=N):
    x=set()
    y=set()
    A=0
    B=0
    for i in range(N):
        if seq[i]==0:
            x.add(X[i])
            A^=(1<<i)
        if seq[i]==1:
            y.add(Y[i])
            B^=(1<<i)
    K=len(x)+len(y)
    tmp=0
    for i in range(N):
        tmp+=min(NS[A][i],WE[B][i])*P[i]
    ans[K]=min(ans[K],tmp)
for line in ans:
    print(line)

Submission status: Time Limit Exceeded

Solution code:
import random


n = int(input())
info = [list(map(int, input().split())) for i in range(n)]
INF = 10 ** 13

n = 15
info = []
for i in range(n):
    info.append([random.randint(-10000, 10000), random.randint(-10000, 10000), random.randint(1, 1000000)])


costs = [INF] * n
for i, (x, y, c) in enumerate(info):
    costs[i] = c * min(abs(x), abs(y))


x_dir = [INF] * ((1 << n) * n)
y_dir = [INF] * ((1 << n) * n)
OFFSET = (1 << n)


for bit_state in range(1 << n):
    for i, (xi, yi, c) in enumerate(info):
        x_dir[bit_state + i * OFFSET] = min(costs[i], x_dir[bit_state + i * OFFSET])
        y_dir[bit_state + i * OFFSET] = min(costs[i], y_dir[bit_state + i * OFFSET])
        if not((bit_state >> i) & 1):
            continue
        for j, (xj, yj, c) in enumerate(info):
            x_dir[bit_state + j * OFFSET] = min(x_dir[bit_state + j * OFFSET], c * abs(yi - yj))
            y_dir[bit_state + j * OFFSET] = min(y_dir[bit_state + j * OFFSET], c * abs(xi - xj))


ans = [INF] * (n + 1)
for bit_state in range((1 << n) - 1):
    x_bit = bit_state
    cnt = bin(bit_state).count("1")
    while x_bit >= 0:
        x_bit &= bit_state
        # bit_stateの下位集合sub_stateの列挙
        # 処理はじめ
        y_bit = bit_state - x_bit
        tmp = 0
        for i in range(n):
            tmp += min(x_dir[x_bit + i * OFFSET], y_dir[y_bit + i * OFFSET])
        ans[cnt] = min(ans[cnt], tmp)
        # 処理おわり
        x_bit -= 1

ans[-1] = 0
for res in ans:
    print(res)

Submission status: Time Limit Exceeded

Solution code:
def main():
    from itertools import product
    n = int(input())

    x = []
    y = []
    p = []
    for i in range(n):
        xx,yy,pp = map(int,input().split())
        x.append(xx+10000)
        y.append(yy+10000)
        p.append(pp)

    yokomi = [[10**9]*(1<<n) for i in range(n)]
    tatemi = [[10**9]*(1<<n) for i in range(n)]


    for i in range(1<<n):
        yoko = [10000]
        tate = [10000]
        for j in range(n):
            if (i>>j)&1 == 1:
                yoko.append(y[j])
                tate.append(x[j])
        for j in range(n):
            pp = 10**9
            qq = 10**9
            for e in yoko:
                if pp > abs(e-y[j]):
                    pp = abs(e-y[j])
            for e in tate:
                if qq > abs(e-x[j]):
                    qq = min(qq,abs(e-x[j]))
            yokomi[j][i] = pp
            tatemi[j][i] = qq

    def iter_p_adic(p, n):
        tmp = [range(p)] * n
        return product(*tmp)

    res = [10**20]*(n+1)


    iterator = iter_p_adic(3,n)
    for idxs in iterator:
        yoko = set([10000])
        tate = set([10000])
        
        xn = 0
        yn = 0
        for i in range(n):
            if idxs[i] == 1:
                yoko.add(y[i])
                yn += 1<<i
            elif idxs[i] == 2:
                tate.add(x[i])
                xn += 1<<i

        tmp = 0
        for i in range(n):
            if idxs[i] == 0:
                mi = min(tatemi[i][xn],yokomi[i][yn])
                tmp += p[i]*mi

        residx = len(yoko) + len(tate) - 2
        if residx < n+1 and res[residx] > tmp:
            res[residx] = tmp
    for e in res:
        print(e)

if __name__ == '__main__':
    main()

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
X = []
Y = []
P = []
for _ in range(N):
    x, y, p = map(int, input().split())
    X.append(x)
    Y.append(y)
    P.append(p)

DX = [[0] * (1 << N) for _ in range(N)]
DY = [[0] * (1 << N) for _ in range(N)]

for i, x in enumerate(X):
    for k in range(1 << N):
        d = abs(x)
        for j, xx in enumerate(X):
            if k & (1 << j):
                d = min(d, abs(xx - x))
        DX[i][k] = d * P[i]
for i, y in enumerate(Y):
    for k in range(1 << N):
        d = abs(y)
        for j, yy in enumerate(Y):
            if k & (1 << j):
                d = min(d, abs(yy - y))
        DY[i][k] = d * P[i]

ANS = [1 << 100] * (N + 1)
PC = [0] * (1 << N)
for i in range(1, 1 << N):
    j = i ^ (i & (-i))
    PC[i] = PC[j] + 1

for i in range(1 << N):
    m = i ^ ((1 << N) - 1)
    j = m
    while 1:
        ans = 0
        for k in range(N):
            ans += min(DX[k][i], DY[k][j])
        
        pc = PC[i] + PC[j]
        ANS[pc] = min(ANS[pc], ans)
        
        if not j:
            break
        j = m & (j - 1)

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

Submission status: Time Limit Exceeded

Solution code:
# Fast IO (only use in integer input)

# import os,io
# input=io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

from copy import copy

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

minCost = [-1] * (N+1)

preCalRange = 1 << N

horizontalLineDistance = []
verticalLineDistance = []

for i in range(preCalRange):
    railRoad = []
    tmp = i
    for j in range(N):
        railRoad.append(tmp % 2)
        tmp //= 2
    minDistance = [-1] * N
    for j in range(N):
        minDistance[j] = min(abs(Resident[j][0]),abs(Resident[j][1]))
        for k in range(N):
            if railRoad[k] == 1 and abs(Resident[j][0] - Resident[k][0]) < minDistance[j]:
                minDistance[j] = abs(Resident[j][0] - Resident[k][0])
    horizontalLineDistance.append(copy(minDistance))
    minDistance = [-1] * N
    for j in range(N):
        minDistance[j] = min(abs(Resident[j][0]),abs(Resident[j][1]))
        for k in range(N):
            if railRoad[k] == 1 and abs(Resident[j][1] - Resident[k][1]) < minDistance[j]:
                minDistance[j] = abs(Resident[j][1] - Resident[k][1])
    verticalLineDistance.append(copy(minDistance))

totalCases = 3 ** N

for i in range(totalCases):
    railRoad = []
    tmp = i
    for j in range(N):
        railRoad.append(tmp % 3)
        tmp //= 3
    horizontalCount = 0
    verticalCount = 0
    numNewRailroad = 0
    for j in range(N):
        if railRoad[j] == 1:
            numNewRailroad += 1
            horizontalCount += 1 << j
        if railRoad[j] == 2:
            verticalCount += 1 << j
            numNewRailroad += 1
    minDistance = []
    for j in range(N):
        minDistance.append(min(horizontalLineDistance[horizontalCount][j], verticalLineDistance[verticalCount][j]))

    cost = 0
    for j in range(N):
        cost += Resident[j][2] * minDistance[j]
    if minCost[numNewRailroad] == -1 or minCost[numNewRailroad] > cost:
        minCost[numNewRailroad] = cost
for elem in minCost:
    print(elem)

Submission status: Time Limit Exceeded

Solution code:
import itertools
N=int(input())
X=[0 for i in range(N)]
Y=[0 for i in range(N)]
P=[0 for i in range(N)]
for i in range(N):
    X[i],Y[i],P[i]=map(int,input().split())
INF=10**15
ans=[INF for i in range(N+1)]
NS=[[0 for j in range(N)] for i in range(2**N)]
WE=[[0 for j in range(N)] for i in range(2**N)]
for seq in itertools.product(range(2),repeat=N):
    num=0
    for i in range(N):
        if seq[i]==1:
            num^=(1<<i)
    for i in range(N):
        tmp=abs(Y[i])
        for j in range(N):
            if seq[j]==1:
                tmp=min(tmp,abs(X[j]-X[i]))
        NS[num][i]=tmp
for seq in itertools.product(range(2),repeat=N):
    num=0
    for i in range(N):
        if seq[i]==1:
            num^=(1<<i)
    for i in range(N):
        tmp=abs(X[i])
        for j in range(N):
            if seq[j]==1:
                tmp=min(tmp,abs(Y[j]-Y[i]))
        WE[num][i]=tmp
for seq in itertools.product(range(3),repeat=N):
    x=set()
    y=set()
    A=0
    B=0
    for i in range(N):
        if seq[i]==0:
            x.add(X[i])
            A^=(1<<i)
        if seq[i]==1:
            y.add(Y[i])
            B^=(1<<i)
    K=len(x)+len(y)
    tmp=0
    for i in range(N):
        tmp+=min(NS[A][i],WE[B][i])*P[i]
    ans[K]=min(ans[K],tmp)
for line in ans:
    print(line)

Submission status: Time Limit Exceeded

Solution code:
def popcnt(n):
    c = (n & 0x5555) + ((n>>1) & 0x5555)
    c = (c & 0x3333) + ((c>>2) & 0x3333)
    c = (c & 0x0f0f) + ((c>>4) & 0x0f0f)
    c = (c & 0x00ff) + ((c>>8) & 0x00ff)
    return c

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

DX = [[0] * (1 << N) for _ in range(N)]
DY = [[0] * (1 << N) for _ in range(N)]

for i, x in enumerate(X):
    for k in range(1 << N):
        d = abs(x)
        for j, xx in enumerate(X):
            if k & (1 << j):
                d = min(d, abs(xx - x))
        DX[i][k] = d * P[i]
for i, y in enumerate(Y):
    for k in range(1 << N):
        d = abs(y)
        for j, yy in enumerate(Y):
            if k & (1 << j):
                d = min(d, abs(yy - y))
        DY[i][k] = d * P[i]

ANS = [1 << 100] * (N + 1)

for i in range(1 << N):
    m = i ^ ((1 << N) - 1)
    j = m
    pci = popcnt(i)
    while 1:
        ans = 0
        for k in range(N):
            ans += min(DX[k][i], DY[k][j])
        
        pc = pci + popcnt(j)
        ANS[pc] = min(ANS[pc], ans)
        
        if not j:
            break
        j = m & (j - 1)

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

Submission status: Time Limit Exceeded

Solution code:
# Fast IO (only use in integer input)

import os,io
input=io.BytesIO(os.read(0,os.fstat(0).st_size)).readline

from copy import copy

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

minCost = [-1] * (N+1)

preCalRange = 1 << N

horizontalLineDistance = []
verticalLineDistance = []

for i in range(preCalRange):
    railRoad = []
    tmp = i
    for j in range(N):
        railRoad.append(tmp % 2)
        tmp //= 2
    minDistance = [-1] * N
    for j in range(N):
        minDistance[j] = min(abs(Resident[j][0]),abs(Resident[j][1]))
        for k in range(N):
            if railRoad[k] == 1 and abs(Resident[j][0] - Resident[k][0]) < minDistance[j]:
                minDistance[j] = abs(Resident[j][0] - Resident[k][0])
    horizontalLineDistance.append(copy(minDistance))
    minDistance = [-1] * N
    for j in range(N):
        minDistance[j] = min(abs(Resident[j][0]),abs(Resident[j][1]))
        for k in range(N):
            if railRoad[k] == 1 and abs(Resident[j][1] - Resident[k][1]) < minDistance[j]:
                minDistance[j] = abs(Resident[j][1] - Resident[k][1])
    verticalLineDistance.append(copy(minDistance))

totalCases = 3 ** N

for i in range(totalCases):
    railRoad = []
    tmp = i
    for j in range(N):
        railRoad.append(tmp % 3)
        tmp //= 3
    horizontalCount = 0
    verticalCount = 0
    numNewRailroad = 0
    for j in range(N):
        if railRoad[j] == 1:
            numNewRailroad += 1
            horizontalCount += 1 << j
        if railRoad[j] == 2:
            verticalCount += 1 << j
            numNewRailroad += 1
    minDistance = []
    for j in range(N):
        minDistance.append(min(horizontalLineDistance[horizontalCount][j], verticalLineDistance[verticalCount][j]))

    cost = 0
    for j in range(N):
        cost += Resident[j][2] * minDistance[j]
    if minCost[numNewRailroad] == -1 or minCost[numNewRailroad] > cost:
        minCost[numNewRailroad] = cost
for elem in minCost:
    print(elem)

Submission status: Time Limit Exceeded

Solution code:
N = int(input())
XYP = [tuple(map(int,input().split())) for i in range(N)]

from itertools import combinations
xset = set()
yset = set()
ycands = []
for x,y,_ in XYP:
    if x!=0: xset.add(x)
    if y!=0: yset.add(y)

xl = sorted(list(xset))
yl = sorted(list(yset))
from bisect import bisect

def cost(xs,ys):
    ret = 0
    for x,y,p in XYP:
        tmp = min(abs(x), abs(y))
        i = bisect(xs, x)
        if i:
            tmp = min(tmp, x - xs[i-1])
        if i < len(xs):
            tmp = min(tmp, xs[i] - x)
        i = bisect(ys, y)
        if i:
            tmp = min(tmp, y - ys[i-1])
        if i < len(ys):
            tmp = min(tmp, ys[i] - y)
        ret += tmp * p
    return ret

for k in range(N+1):
    if k >= len(xl) or k >= len(yl):
        print(0)
        continue
    ans = 10**20
    for xc in range(k+1):
        yc = k-xc
        for xs in combinations(xl,xc):
            for ys in combinations(yl,yc):
                ans = min(ans, cost(xs,ys))
    print(ans)