https://www.acmicpc.net/problem/1309


다른 분들은.. 도대체 어떻게 푸신건지.. 잘 이해가 안가더라구요...ㅎㅎ...

저는.. 좀 어렵게 푼듯 하네요... 다른분들은 1차원 dp인데 저는 2차원 dp라고 생각했습니다.


dp[N][3]으로 2차원 dp를 정의했고

N은 칸 수 뒤의 3은


0 = N번째 칸에 사자를 안넣는 경우

1 = 1번째 칸에 사자를 넣는 경우

2 = 2번쨰 칸에 사자를 넣는 경우


라고 생각하고 풀었습니다.


n칸에다가 사자를 안넣는다면

dp[n][0]은 dp[n - 1][0] + dp[n - 1][1] + dp[n - 2][2]입니다.

n칸에다가 사자를 안넣는 경우는 n - 1 칸에서 사자를 안넣는경우, 사자를 1칸에 넣는 경우, 2칸에 넣는경우 셋 다 가능하기 때문입니다.


n의 1칸에 사자를 넣는다면 n-1칸에서는 사자를 안넣거나 2칸에 넣는다면 n의 1칸에 사자를 넣을 수 있으므로 그 두개를 더합니다.


n의 2칸에서는 1칸과 동일하게 n - 1칸에 사자를 안넣는 경우, 1칸에 넣는 경우 두가지를 더합니다.


점화식은..

1
2
3
4
5
6
for(int i = 2; i <= n; i++)
{
    dp[i][0= dp[i - 1][0+ dp[i - 1][1+ dp[i - 1][2];
    dp[i][1= dp[i - 1][0+ dp[i - 1][2];
    dp[i][2= dp[i - 1][0+ dp[i - 1][1];
}
cs

입니다!


아래는 풀 코드입니다.


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
#include <cstdio>
#define MAX_SIZE 100001
 
int dp[MAX_SIZE][3];
 
int main()
{
    int n;
    scanf("%d"&n);
 
    for(int i = 0; i < 3; i++) dp[1][i] = 1;
 
    for(int i = 2; i <= n; i++)
    {
        dp[i][0= dp[i - 1][0+ dp[i - 1][1+ dp[i - 1][2];
        dp[i][1= dp[i - 1][0+ dp[i - 1][2];
        dp[i][2= dp[i - 1][0+ dp[i - 1][1];
 
        for(int j = 0; j < 3; j++) dp[i][j] %= 9901;
    }
    printf("%d\n", (dp[n][0+ dp[n][1+ dp[n][2])%9901);
 
    return 0;
}
 
cs


'알고리즘 > 다이나믹 프로그래밍(DP)' 카테고리의 다른 글

[2629] 양팔 저울  (0) 2017.04.25
[2133] 타일 채우기  (0) 2017.04.20
[2294] 동전 2  (0) 2017.04.19
[2293] 동전 1  (4) 2017.04.19
[1727] 커플 만들기  (0) 2017.04.05

+ Recent posts