서론
문제 지문과 공식 풀이는 NYPC 아카이브에서 확인할 수 있습니다. 채점은 BIKO에서 받을 수 있습니다.
제가 생각하는 난이도(solved.ac 기준)는 다음과 같습니다.
- Round 1
- 버튼
- [S?] 같이 던전 도실래요?
- [S?] 등차수열
- [S?] 이모티콘 출력
- [G2] 잃어버린 섬 여행
- [G5] 같은 자리 같은 값
- [P3] 최강 장비 세트 (output only)
- [P4] 최대한 빠르게 (output only)
- [-] K주년 (풀이 준비 중)
- [P1] 블루홀 다이빙 챌린지
- Round 2-A
- [S2] 중복
- [P4] 완벽한 음악 연주 시각 찾기
- [D4] 완전한 승리
- [D3] 청소
- Round 2-B
- [S1] 버블
- [G1] 트리의 모든 부분 트리의 크기 합
- [G1] 로봇들의 모험
- [D?] 토벤머리 용사의 스타포스 강화
PC 화면으로 보는 분들은 우측 사이드바를 이용해 원하는 문제로 빠르게 이동할 수 있습니다.
Round 1
1. 버튼
버튼을 $t$번 누른 뒤에 실패하게 되는 경우의 수를 $f(t)$라고 합시다. 문제의 정답은 $K + \sum_{t=1}^{K} t \times f(t)$ 입니다.
$t = 1$일 때는 최악의 경우 $N$번째 시도에서 올바른 버튼을 찾을 수 있으므로 $f(1) = N-1$입니다. $t = 2$일 때는 버튼 하나를 후보에서 제거할 수 있으므로 최대 $N-2$번 실패할 수 있고, 마찬가지로 $t = 3$일 때는 최대 $N-3$번 실패할 수 있습니다. 즉, $f(t) = N - t$입니다.
따라서 $K + \sum_{t=1}^{K} t \times (N-t)$를 출력하면 문제를 해결할 수 있습니다. $K+\frac{NK(K+1)}{2}-\frac{K(K+1)(2K+1)}{6}$을 출력하면 반복문을 사용하지 않고 해결할 수도 있습니다.
1 |
|
2. 같이 던전 도실래요?
두 사람의 플레이 가능 시간을 각각 $A_i, A_j$라고 하면, 파티 시너지는 $A_i + A_j - \vert A_i - A_j \vert$, 던전 클리어 횟수는 $\lfloor \frac{\min(A_i,A_j)}{M} \rfloor$입니다. 잘 생각해 보면 파티 시너지는 $2\times\min(A_i,A_j)$로 계산할 수 있으므로, 최종 스코어를 최대화하기 위해서는 $\min(A_i,A_j)$를 되도록 크게 만들어야 한다는 사실을 알 수 있습니다.
$N$명의 사람을 $A_i$ 오름차순으로 정렬한 뒤, 인접한 두 사람을 같은 팀으로 만들면 최종 스코어의 합을 최대화할 수 있습니다. 전체 시간 복잡도는 $O(N \log N)$입니다.
1 |
|
3. 등차수열
공차가 $d$인 등차수열 $\lbrace A_1,A_2, \cdots, A_N\rbrace$은 $A_i$에서 $i\cdot d$를 빼면 모두 같은 값이 됩니다. 이 성질을 이용해서 문제의 풀이를 찾아봅시다.
주어진 수열을 잘 조작해서 공차가 1인 등차수열을 만드는 것이 목표고, 수열의 각 항에 1 또는 -1을 최대 한 번 더할 수 있습니다. 이는 $A_i - i$에 1 또는 -1을 최대 한 번 더해서 모든 원소의 값이 같아지도록 만드는 문제입니다.
항상 공차가 1인 등차수열을 만들 수 있는 경우만 주어진다고 했으므로 $A_i - i$의 최솟값과 최댓값의 차는 2 이하입니다. 따라서 차가 0일 때, 1일 때, 2일 때로 나누어 문제를 해결하면 됩니다.
1 |
|
4. 이모티콘 출력
단순 구현 문제입니다.
1 |
|
5. 잃어버린 섬 여행
$0\rightarrow 1\rightarrow 0 \rightarrow \cdots$와 $1\rightarrow 0\rightarrow 1\rightarrow \cdots$ 패턴으로 섬을 방문하는 두 가지 방법에서의 방호복 교체 횟수를 각각 구한 뒤 둘 중 더 작은 값을 출력하면 됩니다.
각 방호복마다 갈 수 있는 모든 섬을 방문해야 하는데, 일부 섬들 사이에 DAG 형태의 선후 관계가 주어져 있습니다. 어떤 섬에 갈 수 있다는 것은 정점의 in degree가 0이라는 것을 의미하므로, 위상 정렬을 할 때와 비슷하게 각 정점의 in degree를 관리하면서, 매번 방문할 수 있는 섬을 모두 방문하는 식으로 구현하면 됩니다. 시간 복잡도는 위상 정렬과 동일하게 $O(N+M)$입니다.
1 |
|
6. 같은 자리 같은 값
$A$에서의 시작 위치가 $i$, $B$에서의 시작 위치가 $j$인 두 부분 수열에서 값이 매칭되기 위해서는 $A_{i+t} = B_{j+t}$인 두 원소가 존재해야 합니다. 반대로 이야기하면, 인덱스 차이가 $d = (i+t) - (j+t) = i - j$이면서 값이 같은 모든 원소는 시작 위치가 각각 $i, j$인 부분 수열에서 매칭됩니다.
결국 이 문제는 값이 같고 인덱스 차이가 $d$인 원소 쌍의 수를 모든 $-M < d < N$에 대해 구하는 것으로 해결할 수 있습니다. 일반적으로는 빠르게 풀기 어려운 문제(Convolution)지만, 문제 조건에 의해 두 수열 $A, B$를 통틀어서 같은 값은 최대 3번 등장하므로, $O(N+M)$ 시간에 모든 쌍을 찾을 수 있습니다.
1 |
|
7. 최강 장비 세트
$i$번째 아이템을 선택하면 기본적으로 점수가 $A_i = s_iw_S + d_iw_D + h_iw_H$ 만큼 상승합니다. 만약 장착 부위와 장비가 속한 세트가 모두 같은 장비가 여러 개 있다면, $A_i$가 가장 큰 장비 하나만 남기고 나머지를 지워도 답은 변하지 않습니다.
서로 다른 세트끼리는 점수에 영향을 주지 않으므로, 캐릭터의 최종 스탯 점수는 각 세트마다 얻는 점수의 합으로 계산할 수 있습니다. 따라서 다음과 같은 DP를 생각해 볼 수 있습니다.
- $\text{SetScore}(i, bit) :=$ $bit$에 속한 부위에 $i$번째 세트의 장비를 착용했을 때의 최대 점수
- $D(i, bit) :=$ $1, 2, \cdots, i$번 세트의 장비로 $bit$에 속한 부위의 장비를 착용했을 때의 최대 점수
점화식은 $D(i, bit) = \max_{sub \subset bit} D(i-1, bit\setminus sub) + \text{SetScore}(i, sub)$를 이용해 계산할 수 있습니다. 9개의 원소로 구성된 총 $2^9$개의 집합의 부분 집합을 순회하는 데 걸리는 시간은 $O(3^9)$입니다(이항 정리). 따라서 전체 시간 복잡도는 $O(N + M\times 3^9)$입니다.
1 |
|
8. 최대한 빠르게
$K \le 15$ 정도라면 TSP와 비슷하게 지금까지 획득한 아이템 집합을 비트 연산으로 관리하면서 BFS를 돌리면 $O(N^32^K)$ 정도에 문제를 해결할 수 있습니다. 또한 TSP를 생각했다면 $K > 15$일 때 일반적인 방법으로 풀기 어렵다는 것을 눈치챌 수 있을 것입니다.
$K \le 30$인 데이터에서도 만점을 받는 방법은 여러가지가 있는데, 가장 간단한 방법은 다음과 같습니다.
시뮬레이터를 통해 미로를 보면, 일자로 쭉 뻗은 경로가 그렇게 많지 않고, 경로 자체가 길지도 않습니다. 최대 길이가 약 20 정도이기 때문에 아이템은 그것의 절반인 10개 정도만 사용해도 될 것이라 추측할 수 있고, 실제로 모든 데이터에서 아이템을 10개 이하로 사용하는 최적해가 존재합니다. 이러한 추측을 했다면, 단순히 아이템을 무작위로 10개 선택한 뒤 $K = 10$인 문제를 해결하는 서브루틴을 수백 번 반복하는 것으로 최적해를 찾을 수 있습니다.
힐 클라이밍, 유전 알고리즘, 담금질 기법 등의 방법도 당연히 가능합니다.
1 |
|
9. K주년 - TODO
풀이 준비 중
10. 블루홀 다이빙 챌린지
편의상 입력으로 주어진 $K$ 대신 $K+1$을 $K$로 사용합시다. 상대 좌표가 $(-2K, 0), (-K, -K), (-K, 0), (0, 0)$인 칸은 작살을 한 번 사용하여 공격할 수 있습니다. 이런 식으로 한 개의 작살로 공격할 수 있는 칸들끼리 서로 모은 새로운 보드를 만든다면, 새로운 보드마다 독립적으로 문제를 해결한 뒤에 합치는 것으로 전체 문제를 풀 수 있음을 알 수 있습니다. 구체적으로, $i_1 \equiv i_2 \pmod K, j_1 \equiv j_2 \pmod K, (i_1+j_1) \equiv (i_2+j_2) \pmod{2K}$인 칸끼리 모은 뒤에 해결하면 됩니다.
이 문제는 set cover 문제로 모델링할 수 있고, 일반적으로 set cover 문제는 빠르게 해결하는 것이 매우 어렵습니다(NP-Hard). NP-Hard 문제에는 NP-Hard에 알맞는 풀이를 찾아야 한다는 것을 머리 속에 넣어두고 생각을 전개해 봅시다.
설명과 구현의 편의를 위해 상대 좌표가 $(-2K, 0), (-K, -K), (-K, 0), (0, 0)$인 칸들을 상대 좌표가 $(-1, -1), (-1, 0), (0, -1), (1, 1)$이 되도록 격자를 잘 회전하고 압축합시다. 또한 이들을 공격할 수 있는 작살의 좌표 $(-K, 0)$은 구현의 편의를 위해 $(1, 1)$으로 옮겨줍시다. 이제 이 문제는 $2\times 2$ 크기의 정사각형을 이용해 모든 물고기를 덮는 문제로 바뀌었습니다. 또한 $K \ge 2$이므로 새로 만든 격자의 한 변의 길이는 $\lceil 25/2\rceil$ 이하가 되었습니다. 이런 상황은 비트 DP를 사용하기 매우 좋은 조건입니다. 따라서 격자를 잘 분리하고 변환했다면, 그다음에는 비트 DP와 역추적만 잘 구현하면 문제를 해결할 수 있습니다.
분리된 격자의 크기를 $M\times M$이라고 하면, 비트 DP와 역추적은 $O(M^2 2^M)$ 시간에 수행할 수 있고, $M \approx 13$ 정도로 작기 때문에 제한 시간 내에 문제를 해결할 수 있습니다.
1 |
|
Round 2-A
1. 중복
입력으로 주어진 $N$개의 수를 오름차순으로 정렬한 뒤 차례대로 $A_1, A_2, \cdots, A_N$이라고 합시다. 길이가 $K$인 구간 $[i, i+K-1]$을 모두 같은 값을 만들기 위한 최소 비용을 모든 $1 \le i \le N-K+1$에 찾는 방식으로 문제를 해결할 것입니다.
$A_i, A_{i+1}, \cdots, A_{i+K-1}$을 모두 어떤 값 $X$로 만들기 위해 필요한 연산의 횟수는 $f_i(X) = \sum_{k=i}^{i+K-1} \vert A_i - X \vert$이고, $X$가 $A_i, A_{i+1}, \cdots, A_{i+K-1}$의 중앙값일 때 $f_i(X)$가 최소가 됨이 잘 알려져 있습니다. 따라서 누적 합 배열을 이용하면 구간마다 상수 시간에 $f_i(X)$의 최솟값을 구할 수 있습니다.
입력으로 주어진 수를 정렬하는 데 $O(N \log N)$, 누적 합 배열을 만드는 데 $O(N)$, 구간마다 필요한 최소 연산 횟수를 구하는 데 $O(N)$ 만큼이 연산이 필요하므로 전체 시간 복잡도는 $O(N \log N)$입니다.
1 |
|
2. 완벽한 음악 연주시각 찾기
$D(i, j) :=$ $i$번째 음표까지 연주했고, $i$번째 음표를 연주한 시각이 $j$일 때의 최소 오차라고 정의합시다.
점화식은 $D(i, j) = \min_{L_{i-1} \le k \le \min(R_{i-1}, j-x)} D(i-1, k) + \vert j - P_i \vert$ (단, $L_i \le j \le R_i$)와 같이 나타낼 수 있으며, naive하게 계산하면 $O(NX^2)$이 되어 서브태스크 2를 해결할 수 있습니다.
$\min D(i-1, k)$를 구하는 것은 사실 $D(i-1, \ast)$의 시작점이 $L_{i-1}$인 prefix min을 구하는 것과 같습니다. 따라서 prefix min을 전처리하거나 $j$를 증가시키면서 누적 최솟값을 관리하는 것을 통해 $O(NX)$로 최적화할 수 있고, 서브태스크 3을 해결할 수 있습니다.
모든 $L_i \le j \le R_i$를 고려하는 대신 $L_i, T_i, R_i$만 확인해도 된다는 사실을 이용하면 좌표 압축을 통해 DP 테이블의 크기를 $3N^2$으로 줄일 수 있습니다. 이 경우 시간 복잡도는 $O(N^2)$이 되어 100점을 받을 수 있습니다.
$L_i, T_i, R_i$ 대신 $L_i - ix, T_i - ix, R_i - ix$를 사용하면 $D(i, j) = \min_{k \le j} + \vert j - P_i \vert$처럼 되어 최솟값을 구하는 구간의 형태가 간단해 집니다.
1 |
|
3. 완전한 승리
모든 점 $(X, Y)$에 대해, 파란 점 $(x_b, y_b) \in B$는 $x_b \le X, y_b \le Y$, 빨간 점 $(x_r, y_r) \in R$은 $x_r > X, y_r > Y$가 되도록 만드는 최소 이동 횟수를 구하는 방식으로 접근합시다. 만약 한 번에 여러 개의 점을 이동시킬 수 있다면 $(X, Y)$에서의 정답은 $N$에서 (이동하지 않아도 되는 점의 개수)를 뺀 값, 즉 $N - #\lbrace (x_b,y_b) \in B; x_b \le X, y_b \le Y\rbrace - #\lbrace(x_r,y_r) \in R; x_r > X, y_r > Y\rbrace$ 입니다.
하지만 이 문제는 점을 한 번에 하나씩만 이동해야 합니다. 이 경우에는 $(X, Y)$의 좌하단 영역과 우상단 영역에 모두 빈 칸이 없을 때 정답이 1 만큼 증가하고, 그렇지 않은 경우에는 점을 여러 개 이동시킬 수 있는 문제에서의 정답과 같습니다.
$(X, Y)$를 $X$좌표가 증가하는 순서대로 보는 형태의 스위핑을 이용해 문제를 해결합시다. 각각의 $Y$좌표마다 분할점을 $(X, Y)$로 했을 때 옮기지 않아도 되는 점의 개수를 관리하면, 구간 최댓값 쿼리를 이용해 문제를 해결할 수 있습니다. 따라서 $Y$좌표마다 옮기지 않아도 되는 점의 개수를 세그먼트 트리로 관리합니다.
구체적으로, $X = -\infty$일 때는 $Y < y_r$이면 빨간 점 $(x_r, y_r)$을 옮기지 않아도 됩니다. 따라서 초기에 모든 빨간 점 $(x_r, y_r)$에 대해, $[1, y_r-1]$ 구간에 1씩 더한 상태로 시작합시다.
이후 $X$가 증가함에 따라 점의 정보를 갱신해야 합니다. $X = k$에서 $X = k+1$로 이동하면 $x_r = k+1$인 빨간 점은 모두 이동이 필요하며, $x_b = k+1$인 파란 점은 $Y \ge y_b$일 때 이동하지 않아도 됩니다. 따라서 $x_r = k+1$인 빨간 점이 있다면 $[1, y_r-1]$ 구간에 1을 빼고, $x_b = k+1$인 파란 점이 있다면 $[y_b, M]$ 구간에 1을 더해야 합니다.
이런 식으로 세그먼트 트리에 정보를 올바르게 저장했다면, 이제 고정된 $X$에 대해 가능한 $Y$에서의 최댓값을 구할 차례입니다. 파란 점이 있을 수 있는 $x$좌표 구간의 길이는 $X$이고, 파란 점이 있을 수 있는 $x$좌표 구간의 길이는 $M-x$입니다. 따라서 파란 점과 빨간 점의 개수를 각각 $C_b, C_r$이라고 하면 $\lceil C_b / X \rceil \le Y \le M - \lceil C_r / (M-X) \rceil$ 인 $Y$만 고려해야 합니다. 만약 이러한 $Y$가 존재하지 않으면 주어진 $X$에서 답이 존재하지 않는 것이고, $Y$가 존재하면 구간 최댓값 쿼리를 이용해 답을 구하면 됩니다.
이때 앞에서 이야기한 예외를 신경써야 하는데, $(X, Y)$의 좌하단 영역과 우상단 영역에 모두 빈 칸이 없는 경우를 잘 판별해야 합니다. 이는 처리하는 방법은 아래 코드의 63-65번째 줄을 참고하시길 바랍니다.
1 |
|
4. 청소
2개의 점이 band의 한쪽 경계 위에 있는 최적해가 항상 존재함을 관찰합시다. 그러면 이 문제는 임의의 두 점을 연결하는 직선의 왼쪽(또는 오른쪽)에서, 직선과 거리가 $L$ 이하인 점의 개수를 세는 문제라고 생각할 수 있습니다.
이와 같은 문제를 해결하기 위해서는, 일단 주어진 기울기에 대해서 점들을 정렬한 뒤에 이분 탐색을 이용해 거리가 $L$ 이하인 점의 개수를 구해야 합니다. 불도저 트릭을 이용하면 가능한 $N(N-1)/2$가지 기울기에서의 정렬 순서를 $O(N^2 log N)$에 모두 구할 수 있고, 이후 이분 탐색을 이용해 각 기울기에 대해 $O(\log N)$에 답을 구할 수 있습니다. 따라서 전체 시간 복잡도는 $O(N^2 \log N)$입니다.
한 가지 조심해야 하는 점은, 실수 오차에 굉장히 민감한 문제입니다. $N = 3$에서도 double
과 long double
을 모두 터뜨리는 데이터를 만들 수 있으므로, 정수 타입만 이용해서 모든 계산을 수행해야 합니다. 구체적으로, 기울기의 법선 벡터 $\overrightarrow{n}(x, y)$와 그 벡터의 길이 $d = \sqrt{x^2+y^2}$가 주어지면, $\frac{\vert n \cdot p_i - n \cdot p_j \vert}{d} \le L$를 이용해 두 점 $p_i, p_j$의 거리가 $L$ 이하인지 판별할 수 있습니다. $d > 0$이므로 $d$를 오른쪽으로 넘긴 뒤 양변을 제곱하면 정수 타입만 이용해서 거리를 비교할 수 있습니다. 이때 계산 과정에서 등장하는 수의 크기가 좌표 범위의 네제곱 스케일까지 커질 수 있으므로 __int128_t
와 같은 128비트 정수 자료형을 사용해야 합니다.
1 |
|
Round 2-B
1. 버블
$A_i$를 첫 번째 위치로 옮길 때, $N$번째 위치에 올 수 있는 최댓값을 구하는 식으로 문제를 해결합니다.
$A_i$를 첫 번째 위치로 옮기는 과정에서 $i-1$번의 교환이 필요하고, 이후 $A_j$ (단, $i \ne j$)를 $N$번째 위치로 옮길 때 $N-j-[j<i]$번의 교환이 필요합니다. 이때 $[\text{condition}]$은 아이버슨 괄호로, condition이 참이면 1, 거짓이면 0을 의미합니다. 따라서 $N-j-[j<i] \le K-(i-1)$을 만족하는 모든 $j$들 중 $A_j$의 최댓값을 구하면 문제를 해결할 수 있습니다.
$A_i$를 맨 앞으로 옮긴 뒤에 남은 교환 횟수인 $K-(i-1)$을 $r$이라는 문자로 치환한 뒤에 식을 정리하면, $r < N-i$ 이면 $A[N-r\cdots N]$의 최댓값, $r \ge N-i$ 이면 $A[N-rem-1\cdots N]$의 최댓값을 구하면 된다는 것을 알 수 있습니다. 주어진 수열 $A$의 suffix max를 전처리하면 $O(N)$ 시간에 답을 구할 수 있습니다.
똑같은 값이 첫 번째와 $N$번째에 모두 들어가게 되는 경우를 제외해야 하지 않냐는 의문이 생길 수 있는데, 그러한 동작을 하기 위해서는 $K \ge N-1$이어야 하고, $K \ge N-1$이면 정답이 항상 0 초과이기 때문에 따로 예외 처리를 하지 않더라도 계산 결과에 영향을 주지 않습니다.
1 |
|
2. 트리의 모든 부분 트리의 크기 합
모든 정점의 자손의 수의 합은 모든 정점의 조상의 수의 합과 같습니다. 즉, 서브 트리 크기의 합을 구하는 대신 모든 정점의 높이의 합을 구하는 문제로 생각해도 괜찮습니다. 따라서 모든 $h$에 대해 높이가 $h$인 정점의 개수를 구하는 것으로 문제를 해결할 수 있습니다.
시간 복잡도는 트리의 높이에 비례하는데, $K \ge 2$이면 트리의 높이가 $O(\log_K N)$이 되어 괜찮지만 $K = 1$일 때가 문제입니다. $K = 1$일 때는 답이 $N(N+1)/2$임을 쉽게 알 수 있으므로 이 경우만 예외 처리하면 문제를 풀 수 있습니다. $P$가 짝수가 될 수 있음에 유의해야 합니다.
1 |
|
3. 로봇들의 모험
가장 마지막에 사용하는 로봇은 $K_i \ge 0$을 만족해야 하고, 뒤에서 두 번째로 사용하는 로봇은 $K_i \ge 1$을 만족해야 합니다. 비슷하게, 뒤에서 $t$번째로 사용하는 로봇은 $K_i \ge t-1$을 만족해야 합니다. 이를 이용하면 $K_i$가 단조감소하도록 로봇을 사용하는 최적해가 항상 존재함을 증명할 수 있습니다. 이제부터는 $K_i$가 단조감소하는 해만 고려하겠습니다.
위에서 본 부등식을 생각해 보면, $K_i \ge N$인 로봇을 최대 1개, $K_i \ge N-1$인 로봇을 최대 1개, $\cdots$ , $K_i \ge 0$인 로봇을 최대 1개 선택하는 것으로 유효한 해를 만들 수 있고, 유효한 해는 항상 이런 식으로 만들 수 있다는 것을 알 수 있습니다. 따라서 $K_i$가 큰 로봇부터 차례대로 보면서 매번 아직 선택하지 않은 로봇 중 $D_i$가 가장 큰 로봇을 선택하는 그리디 전략이 성립하고, 우선순위 큐 등을 이용해 $O(N \log N)$ 시간에 문제를 해결할 수 있습니다.
이러한 그리디 전략이 성립하는 이유와, $K_i$가 작은 로봇부터 보면 안 되는 이유를 고민해 보면 좋을 것입니다.
로봇의 집합을 $S$, 유효한 해를 구성하는 로봇 집합들의 집합을 $I$라고 정의하면 $M = (S, I)$는 매트로이드 구조를 이룬다는 것을 이용한 풀이도 있습니다. 단, independence oracle을 $O(N)$보다 빠르게 구현해야 100점을 받을 수 있습니다.
1 |
|
4. 토벤머리 용사의 스타포스 강화
레벨이 $i$인 장비를 $N$으로 만들기 위해 필요한 비용의 기댓값을 $E(i)$라고 합시다. $E(N) = 0$이고, $E(0)$을 최소화해야 합니다.
현재 레벨이 $i$일 때 $i \rightarrow d$ 하락 방지 쿠폰을 구매하는 상황을 생각해 봅시다. 레벨이 $j$가 되는 이벤트가 발생했을 때 실제로 도달하게 되는 레벨을 $next(i,j,d)$라고 정의하면, $E(i)$는 다음과 같은 부등식이 성립함을 알 수 있습니다. 또한, 최적 전략에 해당하는 $d$에서 등호가 성립합니다. (단, $-1 \le d < i$; $D(i, -1) = 0$)
\[E(i) \le C_i + D(i, d) + \sum_{j=0}^N P_{i,j}E(next(i,j,d))\] \[E(i) - \sum_{j=0}^N P_{i,j}E(next(i,j,d)) \le C_i + D(i, d)\]즉, $A_{t,0}E(0) + A_{t,1}E(1) + \cdots + a_{t,N-1}E(N-1) \le B_t$ 꼴의 부등식이 여러 개 주어지면, 모든 부등식이 참이 되도록 할 때 가능한 $E(0)$의 최댓값을 구하는 것으로 문제를 해결할 수 있습니다. (단, $E(i) \ge 0$; $E(N) = 0$)
이러한 형태의 문제를 선형 계획법(Linear Programming)이라고 부르고, Problem Solving 범위에서는 Simplex method를 이용해 해결하는 방법이 널리 알려져 있습니다. 따라서 Simplex method 구현체를 이용하거나, NYPC 채점 시스템에서 지원되는 SciPy의 scipy.optimize.linprog
를 이용하면 문제를 해결할 수 있습니다.
1 |
|
1 |
|