Destroy it! (Codeforces 1176F)
Tags: Implement, sortings

You are playing a computer card game called Splay the Sire. Currently you are struggling to defeat the final boss of the game.The boss battle consists of $$$n$$$ turns. During each turn, you will get several cards. Each card has two parameters: its cost $$$c_i$$$ and damage $$$d_i$$$. You may play some of your cards during each turn in some sequence (you choose the cards and the exact order they are played), as long as the total cost of the cards you play during the turn does not exceed $$$3$$$. After playing some (possibly zero) cards, you end your turn, and all cards you didn't play are discarded. Note that you can use each card at most once.Your character has also found an artifact that boosts the damage of some of your actions: every $$$10$$$-th card you play deals double damage.What is the maximum possible damage you can deal during $$$n$$$ turns?

Input: The first line contains one integer $$$n$$$ ($$$1 \le n \le 2 \cdot 10^5$$$) — the number of turns.Then $$$n$$$ blocks of input follow, the $$$i$$$-th block representing the cards you get during the $$$i$$$-th turn.Each block begins with a line containing one integer $$$k_i$$$ ($$$1 \le k_i \le 2 \cdot 10^5$$$) — the number of cards you get during $$$i$$$-th turn. Then $$$k_i$$$ lines follow, each containing two integers $$$c_j$$$ and $$$d_j$$$ ($$$1 \le c_j \le 3$$$, $$$1 \le d_j \le 10^9$$$) — the parameters of the corresponding card.It is guaranteed that $$$\sum \limits_{i = 1}^{n} k_i \le 2 \cdot 10^5$$$.

Output: Print one integer — the maximum damage you may deal.

Note: In the example test the best course of action is as follows:During the first turn, play all three cards in any order and deal $$$18$$$ damage.During the second turn, play both cards and deal $$$7$$$ damage.During the third turn, play the first and the third card and deal $$$13$$$ damage.During the fourth turn, play the first and the third card and deal $$$25$$$ damage.During the fifth turn, play the only card, which will deal double damage ($$$200$$$).

Sample Inputs:
5
3
1 6
1 7
1 5
2
1 4
1 3
3
1 10
3 5
2 3
3
1 15
2 4
1 10
1
1 100

Sample Outputs:
263

Solution (Python):
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = 'x' in file.mode or 'r' not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b'\n') + (not b)
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            (self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode('ascii'))
        self.read = lambda : self.buffer.read().decode('ascii')
        self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
inf = float('inf')
n = int(input())
ref = [None for _ in range(n)]
for i in range(n):
    (x1, x2, x3, y, z) = (0.0, 0.0, 0.0, 0.0, 0.0)
    for nk in range(int(input())):
        (c, d) = map(int, input().split())
        d = float(d)
        if c == 1:
            if d >= x3:
                (x1, x2, x3) = (x2, x3, d)
            elif d >= x2:
                (x1, x2) = (x2, d)
            elif d >= x1:
                x1 = d
        elif c == 2:
            y = max(y, d)
        else:
            z = max(z, d)
    ref[i] = (x1, x2, x3, y, z)
dp = [0.0] * 10
for i in range(n - 1, -1, -1):
    new_dp = [0.0] * 10
    (x1, x2, x3, y, z) = ref[i]
    for m in range(10):
        case1 = dp[m]
        case2 = dp[(m + 1) % 10] + max(x3, y, z)
        if m + 1 >= 10:
            case2 += max(x3, y, z)
        case3 = dp[(m + 2) % 10] + x2 + x3 if x2 != 0 else -inf
        case4 = dp[(m + 2) % 10] + x3 + y if y != 0 and x3 != 0 else -inf
        if m + 2 >= 10:
            case3 += x3
            case4 += max(x3, y)
        case5 = dp[(m + 3) % 10] + x1 + x2 + x3 if x1 != 0 else -inf
        if m + 3 >= 10:
            case5 += x3
        new_dp[m] = max(case1, case2, case3, case4, case5)
    dp = new_dp[:]
print(int(dp[0]))

Solution (Python):
import sys
input = sys.stdin.readline
n = int(input())
dp0 = [-1] * 10
dp = [-1] * 10
dp0[0] = 0
for _ in range(n):
    k = int(input())
    x = [[] for _ in range(4)]
    for _ in range(k):
        (c, d) = map(int, input().split())
        x[c].append(d)
    for i in range(1, 4):
        x[i].sort(reverse=True)
    y = [[] for _ in range(4)]
    if len(x[1]) >= 3:
        s = 0
        for j in range(3):
            s += x[1][j]
        y[3].append((s, x[1][0]))
    if len(x[1]) >= 2:
        s = 0
        for j in range(2):
            s += x[1][j]
        y[2].append((s, x[1][0]))
    if len(x[1]) >= 1 and len(x[2]) >= 1:
        s = x[1][0] + x[2][0]
        m = max(x[1][0], x[2][0])
        y[2].append((s, m))
    m = 0
    for i in range(1, 4):
        if x[i]:
            m = max(m, x[i][0])
    y[1].append((m, m))
    y[0].append((0, 0))
    for i in range(10):
        if dp0[i] < 0:
            continue
        dp0i = dp0[i]
        for j in range(4):
            k = (i + j) % 10
            if i + j < 10:
                for (s, m) in y[j]:
                    dp[k] = max(dp[k], dp0i + s)
            else:
                for (s, m) in y[j]:
                    dp[k] = max(dp[k], dp0i + s + m)
    for i in range(10):
        dp0[i] = dp[i]
        dp[i] = -1
ans = max(dp0)
print(ans)

Solution (Python):
import os
import sys
from io import BytesIO, IOBase

def main():
    inf = -float('inf')
    n = int(input())
    dp = [[inf] * 10 for _ in range(2)]
    dp[0][0] = 0
    for i in range(1, n + 1):
        x = [[], [], [], []]
        for _ in range(int(input())):
            (a, b) = map(int, input().split())
            x[a].append(b)
        for j in range(1, 4):
            x[j].sort(reverse=1)
        for j in range(1, 4):
            while len(x[j]) < 3:
                x[j].append(inf)
        pt1 = max(x[1][0], x[2][0], x[3][0])
        pt2 = max(x[1][0] + x[1][1], x[1][0] + x[2][0])
        pt3 = x[1][0] + x[1][1] + x[1][2]
        a1 = 2 * pt1
        a2 = max(2 * x[1][0] + x[1][1], x[1][0] + x[2][0] + max(x[1][0], x[2][0]))
        a3 = pt3 + x[1][0]
        for j in range(10):
            dp[1][(j + 1) % 10] = max(dp[1][(j + 1) % 10], dp[0][j] + (a1 if j == 9 else pt1))
            dp[1][(j + 2) % 10] = max(dp[1][(j + 2) % 10], dp[0][j] + (a2 if j >= 8 else pt2))
            dp[1][(j + 3) % 10] = max(dp[1][(j + 3) % 10], dp[0][j] + (a3 if j >= 7 else pt3))
        for j in range(10):
            dp[0][j] = max(dp[0][j], dp[1][j])
    print(max(dp[0]))
BUFSIZE = 8192

class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = 'x' in file.mode or 'r' not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b'\n') + (not b)
            ptr = self.buffer.tell()
            (self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            (self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode('ascii'))
        self.read = lambda : self.buffer.read().decode('ascii')
        self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
if __name__ == '__main__':
    main()