1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
  | # 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
import sys
from collections import deque
def main():
    input = sys.stdin.readline
    N, M, S, E, T = map(int, input().split())
    INF = 4 * 10**18
    prefix = [[0]*(M+1) for _ in range(N)]
    for i in range(N):
        arr = list(map(int, input().split()))
        ps = prefix[i]
        for j, c in enumerate(arr, start=1):
            ps[j] = ps[j-1] + c
    banned = [int(input())-1 for _ in range(N)]
    dq = [deque() for _ in range(N)]
    dp = [INF]*N
    minV1 = [INF]*(M+1)
    minV2 = [INF]*(M+1)
    minV3 = [INF]*(M+1)
    minI1 = [-1]*(M+1)
    minI2 = [-1]*(M+1)
    minI3 = [-1]*(M+1)
    def choose_prev(t, i):
        v1, v2, v3 = minV1[t], minV2[t], minV3[t]
        i1, i2, i3 = minI1[t], minI2[t], minI3[t]
        if i1 != i and i1 != banned[i]:
            return v1
        if i2 != -1 and i2 != i and i2 != banned[i]:
            return v2
        return v3
    last_pushed_t = -1
    for j in range(1, M+1):
        lbound = max(0, j - E)
        ubound = (j - 1) if (j == M) else (j - S)
        for i in range(N):
            while dq[i] and dq[i][0][0] < lbound:
                dq[i].popleft()
        if ubound > last_pushed_t:
            for t in range(last_pushed_t + 1, ubound + 1):
                if t == 0:
                    for i in range(N):
                        val = 0
                        while dq[i] and dq[i][-1][1] >= val:
                            dq[i].pop()
                        dq[i].append((t, val))
                else:
                    for i in range(N):
                        best_prev = choose_prev(t, i)
                        val = INF if best_prev >= INF//4 else best_prev + T - prefix[i][t]
                        while dq[i] and dq[i][-1][1] >= val:
                            dq[i].pop()
                        dq[i].append((t, val))
            last_pushed_t = ubound
        if ubound >= lbound:
            for i in range(N):
                if not dq[i]:
                    dp[i] = INF
                else:
                    base = dq[i][0][1]
                    dp[i] = INF if base >= INF//4 else base + prefix[i][j]
        else:
            for i in range(N):
                dp[i] = INF
        v1 = v2 = v3 = INF
        i1 = i2 = i3 = -1
        for i in range(N):
            v = dp[i]
            if v < v1:
                v3, i3 = v2, i2
                v2, i2 = v1, i1
                v1, i1 = v, i
            elif v < v2:
                v3, i3 = v2, i2
                v2, i2 = v, i
            elif v < v3:
                v3, i3 = v, i
        minV1[j], minI1[j] = v1, i1
        minV2[j], minI2[j] = v2, i2
        minV3[j], minI3[j] = v3, i3
    ans = min(dp)
    print(ans)
if __name__ == "__main__":
    main()
  |