문제 주소 : 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 |