16157. 블로그 : https://www.acmicpc.net/problem/16157
16157번: 블로그
neighbor 블로그를 운영하는 디디는 매일 아침 풀고 싶은 문제를 미리 정해놓고 글을 올린다. 그리고 매일 밤 각각의 문제에 대하여, 스스로 해결한 경우 파란색, 도움을 받아 해결한 경우 초록
www.acmicpc.net
문제 파악하기
- 블로그에 올린 문제는 3가지 색깔(R, G, B)로 칠하게 됩니다.
- 연속된 문제들은 한번에 같은 색깔로 색을 칠할 수 있습니다.
- 문제들을 각각 원하는 색깔로 칠하기 위해서는 최소 몇 번의 색칠 작업이 필요할 지 구해야 합니다.
- 그렇다면 그리디 알고리즘을 사용하면 문제를 풀 수 있을까요?
문제 해결하기
- 아쉽게도 그리디 알고리즘으로는 최적값을 찾는데 무리가 있습니다.
이 문제는 다이나믹 프로그래밍 알고리즘으로 해결해야 합니다. - 연속된 문제들을 한번에 칠할 수 있다는 점에 초점을 맞춰봅시다. 그럼 우리는 한번에 칠할 수 있는 경우가 보입니다.
바로 시작점과 같은 색깔을 가지는 문제가 오른쪽에 있다면 한번에 칠할 수 있습니다. - 우리는 시작점과 같은 색깔이 있는 경우, 해당 문제까지 칠한 다음에 나머지 구간을 채우는데 필요한 최솟값을 구하면 됩니다.
- DP[l][r][color] = min( DP[l+1][K-1][inp[l]] + DP[K+1][r][color] )
( 여기서 K는 l과 같은 색깔을 가진 문제를 의미합니다. ) - 이렇게 점화식을 설계하면 문제를 해결할 수 있습니다.
소스코드
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
|
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define NMAX 105
#define INF 0x7FFFFFFF
using namespace std;
int N;
int inp[NMAX];
char str[NMAX];
int dp[NMAX][NMAX][5];
int convert(char c) {
switch(c) {
case 'R': return 1;
case 'G': return 2;
default: return 3;
}
}
int sv(int l, int r, int color) {
if(dp[l][r][color] >= 0) return dp[l][r][color];
else if(l>r) return dp[l][r][color] = 0;
else {
int ll, rr;
ll = l;rr = r;
while(ll<=rr and inp[ll]==color) ll++;
while(ll<=rr and inp[rr]==color) rr--;
if(ll > rr) return dp[l][r][color] = 0;
else {
int ret = INF;
for (int i=ll;i<=rr;i++) {
if(inp[i] == inp[ll]) {
ret = min(ret, sv(ll+1, i-1, inp[ll]) + sv(i+1, rr, color) + 1);
}
}
return dp[l][r][color] = ret;
}
}
}
int main() {
scanf("%d", &N);
scanf("%s", str);
for(int i=0;str[i]!='\0';i++) inp[i+1] = convert(str[i]);
memset(dp, -1, sizeof(dp));
printf("%d", sv(1, N, 0));
}
|
cs |
후기
구간을 점화식으로 표현하는 문제입니다. 점화식을 유추하기 나름은 쉬운 문제라고 생각합니다. 구간을 점화식으로 나타내는 DP를 연습하는 사람에게 추천하는 문제입니다.
'문제 노트 > 백준' 카테고리의 다른 글
자물쇠( BOJ 1514 ) (0) | 2021.07.19 |
---|---|
선물 전달( BOJ 1947 ) (0) | 2021.07.15 |
248 게임( BOJ 12031 ) (0) | 2021.06.29 |
크리스마스 트리 꾸미기( BOJ 16468 ) (0) | 2021.06.21 |
Visiting Cows( BOJ 5934 ) (0) | 2021.05.31 |