The Strongest Build (Codeforces 1574D)
Tags: Greedy, hashing

Ivan is playing yet another roguelike computer game. He controls a single hero in the game. The hero has $$$n$$$ equipment slots. There is a list of $$$c_i$$$ items for the $$$i$$$-th slot, the $$$j$$$-th of them increases the hero strength by $$$a_{i,j}$$$. The items for each slot are pairwise distinct and are listed in the increasing order of their strength increase. So, $$$a_{i,1} < a_{i,2} < \dots < a_{i,c_i}$$$.For each slot Ivan chooses exactly one item. Let the chosen item for the $$$i$$$-th slot be the $$$b_i$$$-th item in the corresponding list. The sequence of choices $$$[b_1, b_2, \dots, b_n]$$$ is called a build.The strength of a build is the sum of the strength increases of the items in it. Some builds are banned from the game. There is a list of $$$m$$$ pairwise distinct banned builds. It's guaranteed that there's at least one build that's not banned.What is the build with the maximum strength that is not banned from the game? If there are multiple builds with maximum strength, print any of them.

Input: The first line contains a single integer $$$n$$$ ($$$1 \le n \le 10$$$) — the number of equipment slots.The $$$i$$$-th of the next $$$n$$$ lines contains the description of the items for the $$$i$$$-th slot. First, one integer $$$c_i$$$ ($$$1 \le c_i \le 2 \cdot 10^5$$$) — the number of items for the $$$i$$$-th slot. Then $$$c_i$$$ integers $$$a_{i,1}, a_{i,2}, \dots, a_{i,c_i}$$$ ($$$1 \le a_{i,1} < a_{i,2} < \dots < a_{i,c_i} \le 10^8$$$).The sum of $$$c_i$$$ doesn't exceed $$$2 \cdot 10^5$$$.The next line contains a single integer $$$m$$$ ($$$0 \le m \le 10^5$$$) — the number of banned builds.Each of the next $$$m$$$ lines contains a description of a banned build — a sequence of $$$n$$$ integers $$$b_1, b_2, \dots, b_n$$$ ($$$1 \le b_i \le c_i$$$).The builds are pairwise distinct, and there's at least one build that's not banned.

Output: Print the build with the maximum strength that is not banned from the game. If there are multiple builds with maximum strength, print any of them.


Sample Inputs:
3
3 1 2 3
2 1 5
3 2 4 6
2
3 2 3
3 2 2

3
3 1 2 3
2 1 5
3 2 4 6
2
3 2 3
2 2 3

3
3 1 2 3
2 1 5
3 2 4 6
2
3 2 3
2 2 3

4
1 10
1 4
1 7
1 3
0

Sample Outputs:
2 2 3

1 2 3

3 2 2

1 1 1 1

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

def readList():
    return list(map(int, input().split()))

def readInt():
    return int(input())

def readInts():
    return map(int, input().split())

def readStr():
    return input().strip()

def solve():
    n = readInt()
    A = [readList() for _ in range(n)]
    m = readInt()
    bs = [readList() for _ in range(m)]
    S = set([tuple(each) for each in bs])
    ans = tuple([each[0] for each in A])
    if ans not in S:
        return ans
    v = 0
    ans = []
    for build in bs:
        for i in range(n):
            if build[i] == 1:
                continue
            build[i] -= 1
            if tuple(build) in S:
                build[i] += 1
                continue
            val = 0
            for j in range(n):
                val += A[j][build[j]]
            if val > v:
                v = val
                ans = list(build)
            build[i] += 1
    return ans
print(*solve())

Solution (Python):
from math import *
from collections import *
from functools import *
from bisect import *
from itertools import *
from heapq import *
import sys
inf = float('inf')
ninf = -float('inf')
ip = sys.stdin.readline
alphal = 'abcdefghijklmnopqrstuvwxyz'
alphau = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
mod = 10 ** 9 + 7

def ipl():
    return list(map(int, ip().split()))

def ipn():
    return int(ip())

def ipf():
    return float(ip())

def solve():
    n = ipn()
    a = [ipl() for _ in range(n)]
    b = set([tuple(ipl()) for _ in range(ipn())])
    h = [(-sum((i[-1] for i in a)), tuple((i[0] for i in a)))]
    s = set()
    while h:
        (ss, tu) = heappop(h)
        if tu not in b:
            print(*tu)
            break
        for i in range(n):
            if tu[i] > 1:
                l = list(tu)
                l[i] -= 1
                l = tuple(l)
                if l not in s:
                    s.add(l)
                    heappush(h, (ss + a[i][tu[i]] - a[i][l[i]], l))
t = 1
for _ in range(t):
    solve()

Solution (Python):
bn = 10 ** 10
n = int(input())
(c, a) = ([], [])
for _ in range(n):
    aa = list(map(int, input().split()))
    c.append(aa[0])
    aa[0] = -bn
    a.append(aa)
bs = {tuple(map(int, input().split())) for _ in range(int(input()))}
m = 0
mb = []
for b in bs:
    b = list(b)
    s = sum((a[i][b[i]] for i in range(n)))
    for i in range(n):
        s -= a[i][b[i]]
        b[i] -= 1
        s += a[i][b[i]]
        if tuple(b) not in bs and s > m:
            m = s
            mb = tuple(b)
        s -= a[i][b[i]]
        b[i] += 1
        s += a[i][b[i]]
print(*(c if tuple(c) not in bs else mb))