
원형으로 연결된 스티커를 뜯어 최댓값을 만드는 문제다. "인접한 것을 사용할 수 없다"는 조건에서 전형적인 DP 점화식을 유도해냈고, "원형"이라는 특수한 조건을 두 개의 일직선 문제로 쪼개어 해결했다.
dp[i-2] + sticker[i])dp[i-1])dp[i] = max(dp[i-1], dp[i-2] + sticker[i])0 ~ N-21 ~ N-1#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int solution(vector<int> sticker)
{
int answer = 0;
int N = sticker.size();
// 예외 처리: 스티커가 한 장뿐일 때
if (N == 1) return sticker[0];
// DP 테이블 초기화
vector<int> dp1(N, 0); // Case 1: 첫 번째 스티커 뜯음
vector<int> dp2(N, 0); // Case 2: 첫 번째 스티커 안 뜯음
// Case 1 진행 (범위: 0 ~ N-2)
dp1[0] = sticker[0];
dp1[1] = sticker[0]; // 1번은 못 뜯으므로 0번 값 유지
for (int i = 2; i < N - 1; ++i)
{
dp1[i] = max(dp1[i - 1], dp1[i - 2] + sticker[i]);
}
// Case 2 진행 (범위: 1 ~ N-1)
dp2[0] = 0; // 0번 안 뜯음
dp2[1] = sticker[1]; // 1번 뜯음
for (int i = 2; i < N; ++i)
{
dp2[i] = max(dp2[i - 1], dp2[i - 2] + sticker[i]);
}
// 두 케이스 중 최댓값 선택
// Case 1의 끝은 N-2, Case 2의 끝은 N-1
answer = max(dp1[N - 2], dp2[N - 1]);
return answer;
}
dp1[N-2] 접근 시 인덱스가 음수가 되어 런타임 에러가 발생할 수 있다.if (N == 1) return sticker[0]; 예외 처리를 추가하여 방어했다.| 항목 | 내용 |
|---|---|
| 유형 | DP (동적 계획법) |
| 체감 난이도 | 중 (점화식만 세우면 구현은 쉬움) |
| 복잡도 | 시간: , 공간: |
| 새로 배운 것 | 원형 배열에서의 DP 접근법 (첫 요소를 포함하느냐 마느냐로 케이스 분리) |