LeetCode 1563. Stone Game V

문제 https://leetcode.com/problems/stone-game-v 풀이 돌이 일렬로 놓여 있고, 매 턴마다 현재 구간을 둘로 나눈 뒤 더 작은 합을 가진 쪽을 가져간다. Alice가 얻을 수 있는 최대 점수를 리턴하는 문제이다. 매 턴마다 현재 구간을 둘로 나눈 뒤 더 작은 합을 가진 쪽을 가져가므로, 구간 DP로 보는 게 자연스럽다. dp[left][right]를 stoneValue[left...right] 구간에서 Alice가 얻을 수 있는 최대 점수라고 하자. 구간을 split으로 나눠서 왼쪽 합과 오른쪽 합을 비교하면 된다. 왼쪽 합이 더 작으면 왼쪽을 가져간다. 오른쪽 합이 더 작으면 오른쪽을 가져간다. 두 합이 같으면 둘 중 더 좋은 쪽을 선택한다. 구간 합은 Prefix Sum으로 미리 구해두면 되고, dp는 짧은 구간부터 채우면 된다. 각 구간마다 모든 분할을 확인하므로 전체 시간 복잡도는 $O(n^3)$이다. ...

August 17, 2026

LeetCode 1140. Stone Game II

문제 https://leetcode.com/problems/stone-game-ii 풀이 돌이 일렬로 놓여 있고, 현재 M일 때 1개부터 2M개까지 가져갈 수 있다. 돌을 가져간 뒤에는 M이 max(M, 가져간 개수)로 바뀐다. Alice가 항상 먼저 시작하고, Alice가 얻을 수 있는 돌의 최대 개수를 구하면 된다. 현재 차례인 사람이 상대보다 얼마나 더 많이 가져갈 수 있는지로 DP를 정의할 수도 있지만, 이 문제에서는 현재 상태에서 현재 플레이어가 최대로 가져갈 수 있는 돌의 수를 저장하는 방식이 더 직관적이다. dp[i][m]을 i번째 돌부터 시작하고 현재 M이 m일 때, 현재 플레이어가 얻을 수 있는 최대 돌의 수라고 하자. suffix[i]는 i번째 돌부터 끝까지 남은 돌의 합이다. ...

August 10, 2026

LeetCode 1510. Stone Game IV

문제 https://leetcode.com/problems/stone-game-iv 풀이 돌이 n개 있고, 매 턴마다 제곱수만큼의 돌을 가져간다. 마지막 돌을 가져가는 사람이 이긴다고 할 때, Alice가 이길 수 있는지 구하면 된다. dp[i]를 돌이 i개 남았을 때 현재 차례인 사람이 이길 수 있는지로 정의한다. 어떤 제곱수 $r^2$을 가져간 뒤 상대 차례의 상태가 패배라면, 현재 플레이어는 그 선택으로 이길 수 있다. 따라서 점화식은 다음과 같다. $$ dp[i] = \text{true} \quad \text{if there exists } r \text{ such that } dp[i - r^2] = \text{false} $$ ...

August 10, 2026

LeetCode 3302. Find the Lexicographically Smallest Valid Sequence

문제 https://leetcode.com/problems/find-the-lexicographically-smallest-valid-sequence 풀이 word1에서 인덱스를 고르고, 그 문자들로 word2를 만들면 된다. 선택한 문자는 순서를 유지해야 하고, word1의 문자 중 최대 하나는 다른 문자로 바꿔서 사용할 수 있다. 가능한 수열 중 인덱스가 사전순으로 가장 작은 것을 구하면 된다. 앞에서부터 무조건 현재 문자가 같은지 확인하면서 고르면 되지만, 문자가 다른 위치에서 변경 기회를 바로 사용해도 뒤쪽에 남은 문자를 모두 맞출 수 있는지 확인해야 한다. 즉, 현재 위치를 선택했을 때 남은 문자의 개수가 충분해야 한다. ...

August 8, 2026

Leetcode 1406. Stone Game III

문제 https://leetcode.com/problems/stone-game-iii 풀이 번호가 적힌 돌이 있고, 두 명(Alice, Bob)이 번갈아 가면서 그 돌을 1개에서 3개까지 가져갈 수 있다. 2명 다 이상적으로 플레이 했을 때, 돌에 적힌 번호를 더한 합이 더 많이 가져간 사람의 이름을 리턴하면 된다. 항상 Alice가 먼저 시작한다. 약간 특이한 DP 문제이다. 점화식을 ‘Alice’ ‘Bob’을 특정하지 않고 ‘현재 차례인 사람이 상대보다 돌을 가질 수 있는 최대 개수’로 정의해야한다. 점화식은 다음과 같다. $$ dp[i] = \max \begin{cases} stoneValue[i] - dp[i+1] \\ stoneValue[i] + stoneValue[i+1] - dp[i+2] \\ stoneValue[i] + stoneValue[i+1] + stoneValue[i+2] - dp[i+3] \end{cases} $$ ...

August 3, 2026

Codeforces 455A. Boredom

문제 https://codeforces.com/problemset/problem/455/A 풀이 풀이 배열a에서 얻을 수 있는 최대 점수를 구하는 DP 문제이다. 어떤 값 x를 선택하면 x만큼의 점수를 얻고, 배열에 있는 x - 1과 x + 1은 모두 제거된다. 여기서 중요한 점은 같은 값을 여러 개 가지고 있다면 하나씩 선택할 이유가 없다는 것이다. x를 선택하는 순간 x - 1과 x + 1은 모두 사용할 수 없으므로, 선택한다면 값이 x인 원소는 모두 선택하는 것이 항상 이득이다. 따라서 입력 배열의 순서는 의미가 없어지고, 각 숫자가 몇 번 등장하는지만 알면 된다. 값 x가 frequencies[x]번 등장한다면, x를 선택했을 때 얻는 점수는 x * frequencies[x]이다. ...

July 31, 2026

Codeforces 189A. Cut Ribbon

문제 https://codeforces.com/problemset/problem/189/A 풀이 길이가 n인 리본이 하나 주어지고, 이를 a, b, c 의 크기로만 조각낼 수 있을 때, 최대로 만들 수 있는 조각의 개수를 출력하는 문제이다. 잘린 리본 조각의 크기가 정해져 있으므로, 그리디가 아니라 DP로 접근해야 한다. 그리디로 접근하면 마지막에 남은 리본 조각의 크기를 확정할 수 없기 때문이다. dp[i]를 길이 i인 리본을 조각냈을 때의 최대 조각 수로 정의하면, 점화식은 다음과 같다. $$dp[i] = \max_{x \in {a, b, c}}(dp[i - x] + 1) \quad \text{if } i \geq x \text{ and } dp[i-x] \neq -1$$ ...

July 29, 2026

Leetcode 3336. Find the Number of Subsequences With Equal GCD

문제 https://leetcode.com/problems/find-the-number-of-subsequences-with-equal-gcd 풀이 수열 nums이 주어지고, nums에서 서로 원소가 겹치지 않게 부분 수열을 두 개 만든 뒤, 각 부분 수열(이하 A, B라 함)의 GCD가 같은 경우의 수를 찾는 문제이다. 만약 브루트 포스를 시도한다면, 원소의 개수 n, 각 원소가 가질 수 있는 상태가 3개(부분 수열 A, 부분 수열 B, 아예 미포함)이므로, 시간 복잡도가 $O(n \times 3^n)$ 이 되는데, nums의 최대 크기가 200이므로 유효한 시간 내에 해결할 수 없다. 하지만 부분 수열을 점점 채워나가면서 두 부분 수열을 비교할 수 있으므로, DP를 사용하면 O(n * 부분 수열A의 최대 gcd * 부분 수열B의 gcd 최대값)이 된다. 문제의 제약조건에서 원소의 최대 크기는 200이고, GCD는 원소보다 클 수 없으므로, $O(n \times 200 \times 200)$으로 줄일 수 있다. ...

July 14, 2026

LeetCode 1301. Number of Paths with Max Score

문제 https://leetcode.com/problems/number-of-paths-with-max-score 풀이 2차원 그리드의 우하단에서 시작해 좌상단까지 이동하면서, 경로에 있는 숫자들의 합의 최대값과 그 최대값이 나오는 경로의 개수를 구하는 문제이다. 최단 거리를 찾는 문제가 아니므로 BFS나 Dijkstra는 필요 없고, 어떻게 경로의 수를 구할지가 핵심이다. 이동 방향은 문제에서 주어져 있으므로, 각 노드에서 인접한 노드들의 값을 활용해 특정 합(v)에 도달하는 경로의 개수를 구할 수 있다. 이런 문제를 효율적으로 푸는 방법은 결국 DP이다. 처음에 점화식을 이렇게 만들었다. dp[r][c][v]: row = r, column = c인 노드에서 지나온 경로에 있는 칸들의 합이 v가 되는 경로의 개수. 테스트 케이스는 통과할 수 있었지만, 실제 제출했을 때는 시간 초과가 되어서 통과하지 못했다. v 차원 때문에 dp공간이 너무 커지는 것이 문제였다. ...

July 5, 2026

Programmers. 거스름돈

문제 https://school.programmers.co.kr/learn/courses/30/lessons/12907 풀이 DP 문제다. 순열인지 조합인지 조심하면 쉽게 풀 수 있다. 문제에서 예시로 든 1, 2, 5원이 있을 때를 생각해보자. (5도 마찬가지지만) 2는 1의 배수이다. 따라서 순열로 하면 ‘3’을 만드는 경우에 1+1+1, 1+2, 2+1 이라는 세 가지 방법이 나오게 된다. 하지만 이 문제는 조합 문제이므로 중복을 제거해야한다. 그러면 중복을 어떻게 제거해야 할까? 작은 동전부터 순서대로 만들면 된다. 이 방법이 조합 DP의 가장 기본적인 방법이다. 가장 작은 동전을 써서 만들 수 있는 조합을 다 만든 다음 DP 테이블에 저장한다. 작은 순서대로 (오름차순으로) 조합을 더한다. 이런 식으로 하면 중복을 방지할 수 있다. 위 예제로 따지면 1원짜리 동전을 먼저 써서 1+1+1을 우선 만들고, 다음에 2원을 써서 1+2를 만든다. 작은 순서대로 하므로 알고리즘 상에서 2+1 같은 방법을 만들지 않는다. ...

August 3, 2025