알고리즘 문제/[백준]

[백준] 8895 막대 배치

latter2005 2020. 12. 18. 22:07

문제 주소 : www.acmicpc.net/problem/8895

 

8895번: 막대 배치

높이가 1, 2, ..., n인 막대 n개가 일렬로 배치되어 있다. 막대를 왼쪽이나 오른쪽에서 보면, 큰 막대가 뒤에있는 작은 막대를 가리게 된다. 아래와 같이 4개의 막대로 이루어진 두 배치를 살펴보자.

www.acmicpc.net

문제 확인

 

DP 문제입니다.

n과 n-1의 관계를 생각해보면 쉽게 풀 수 있습니다.

n개의 막대에서 n 혹은 1 막대를 제거하면 n-1이 됩니다. n막대를 제거하면 1~n-1개의 막대를 나열하는 경우가 되며, 1 막대를 제거하면 2~n 막대를 나열하는 경우이며 모든 막대의 길이를 1 줄이게 되면 1~n-1 막대를 나열하는 경우와 같은 경우의 수를 가집니다.

이 특성을 이용해 n과 n-1의 관계를 이용하여 점화식을 세웁니다.

 

풀이

 

막대 1을 기준으로 생각하면 좀 더 쉽게 풀 수 있습니다.

막대 1이 왼쪽/오른쪽 끝에 위치할 때 막대 1이 사라지게 된다면 n값과 함께 l, r 값이 1 줄게 됩니다.

=> dp[n][l][r] += dp[n-1][l-1][r] + dp[n-1][l][r-1]

막대 1이 0과 n-1 위치 사이인 1~n-2 사이에 위치한 경우 n 값만 1이 줄게 되고 l, r에는 변동이 없습니다.

=> dp[n][l][r] += (n-2) * dp[n-1][l-1][r]

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <cstdio>
int main() {
    long long dp[20][20][20= { 1 };
    for (int n = 1; n < 20; n++
        for (int l = 0; l < 20; l++)
            for (int r = 0; r < 20; r++) {
                dp[n][l][r] = (n - 1)*dp[n - 1][l][r];//사이
                if (l)
                    dp[n][l][r] += dp[n - 1][l - 1][r];//왼쪽 끝
                if (r)
                    dp[n][l][r] += dp[n - 1][l][r - 1];//오른쪽 끝
            }
                
    int t, n, l, r;
    scanf("%d"&t);
    while (t--) {
        scanf("%d%d%d"&n, &l, &r);
        printf("%lld\n", dp[n - 1][l - 1][r - 1]);
    }
}
 
cs
반응형

'알고리즘 문제 > [백준]' 카테고리의 다른 글

[백준] 2315 가로등 끄기  (0) 2020.12.29
[백준] 1150 백업  (0) 2020.12.19
[백준] 15685 드래곤 커브  (0) 2020.12.17
[백준] 2357 최솟값과 최댓값  (0) 2020.12.17
[백준] 10868 최솟값  (0) 2020.12.15