본문 바로가기

알고리즘/백준 풀이

[백준 9465] 스티커


  • 스티커 한 장을 때면 해당 스티커의 상, 하, 좌, 우에 해당하는 스티커를 사용할 수 없다.
  • 스티커의 합이 최대가 되기 위해 스티커를 때는 방법을 구하라.

N제한이 100,000 인 경우이며 대략 경우의 수를 살펴보아도 2^N 정도 되는 복잡도이다. 전부다 땔 수 있는 경우는 아니지만 최대로 때어야 하기에

N은 클 수 밖에 없을 것이며, 완전 탐색으로는 힘들다

-> 따라서, 동적 계획으로 풀면 된다.


열 기준으로 보자.

N열일 때의 최댓값을 구해야 한다. 여기서 N열에 스티커를 땔 수 있는 방법은 3가지이다. 윗쪽을 때거나, 아랫쪽을 때거나, 안 때거나!


1. 안 땐 경우 ( 0 )

n - 1 열은 위, 아래 어디든 스티커를 땔 수 있다.

--> DP(n, 0) = MAX( DP(n-1, 0), DP(n-1, 1), DP(n-1, 2) )


2. 윗쪽을 땐 경우 ( 1 )

n - 1 열은 아래 스티커만 때야 한다.

--> DP(n, 1) = MAX( DP(n-1, 0), DP(n-1, 2) )


3. 아랫쪽을 땐 경우 ( 2 )

n - 1 열은 위쪽 스티커만 떄야 한다.

--> DP(n, 2) = MAX( DP(n-1, 0, DP(n-1, 1) )



0. 기저 사례 : N이 0보다 작은 경우, 방법이 없기에 return 0



int go(int n, int dir) {

if (n == -1) {

return 0;

}


int& ret = dp[n][dir];

if (ret != -1) return ret;


if (dir == 0) {

return ret = tripMax(go(n - 1, 0), go(n - 1, 1), go(n - 1, 2));

}

else if (dir == 1) {

return ret = a[0][n] + max(go(n - 1, 0), go(n - 1, 2));

}

else if (dir == 2) {

return ret = a[1][n] + max(go(n - 1, 0), go(n - 1, 1));

}

}



Review.


각 경우의 수를 잘 생각해보자, 그리고 기저 사례는 항상 중요!

'알고리즘 > 백준 풀이' 카테고리의 다른 글

[백준 7562] 나이트의 이동  (0) 2018.12.17
[백준 1328] 고층 빌딩  (1) 2018.11.29
[백준 2163] 초콜릿 자르기  (0) 2018.11.25
[백준 2667] 단지번호 붙이기  (0) 2018.11.25
[백준 4963] 섬의 개수  (0) 2018.10.05