본문 바로가기

알고리즘/BOJ

1328번

1328번 - 고층 빌딩


점화식 D[N][L][R] = N개의 건물을 봤을 때 왼쪽에서 L개 오른쪽에서 R개인 경우의 수


사실 점화식을 세웠지만, 이 식을 다른 N,L,R 과 연관시키는게 사실 너무 어려웠다.


나도 결국 다른 사람들의 풀이에서 힌트를 얻고 문제를 풀 수 있었다. (다시 풀어봐야겠다)


이 문제는 결국 높이 1의 빌딩을 어느 곳에 놓을 것인가 하는 문제로 끝이난다.


어떻게 다른 사람들은 이걸 생각했는지 참 신기하다...


높이 1의 건물을 맨 왼쪽에 뒀을 때, 맨 오른쪽에 뒀을 때, 그리고 나머지 부분에 뒀을 때로 나뉘게 된다.


가장 작은 건물이기 때문에 맨 왼쪽에 두면 N 과 L 이 1씩 증가.


맨 오른쪽에 두면 N과 R이 1씩 증가.


나머지 부분에 두면 N은 증가하지만 L과 R은 변화가 없다.


따라서 이를 통해 다른 N,L,R 과 D[N][L][R] 을 연결하는 식이 생긴다.


D[N][L][R] = D[N-1][L-1][R] + D[N-1][L][R-1] + D[N-1][L][R] * (N-2) 

                (맨 왼쪽 둘때)    (맨 오른쪽 둘때)   (나머지에 둘 때 경우의 수는 N-2가 된다)


그리고 재귀로 풀 때 초기값은 우선 N=1 일때 L,R은 무조건 1이어야 한다. (조건 1)


그리고 N,L,R 은 무조건 1보다 작으면 안된다.. (조건 2)


그 다음 중요한것은 long long 형을 써야 한다는 사실! 빼먹으면 안된다.


<정답 코드>


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
#include<iostream>
#include<string.h>
 
using namespace std;
const int mod = 1000000007;
long long D[101][101][101];
long long go(int n, int l, int r)
{
    if (n < 1 || l < 1 || r < 1)
    {
        return 0;
    }
    if (n == 1)
    {
        if (l == 1 && r == 1)
        {
            return 1;
        }
        else
        {
            return 0;
        }
        
    }
    if (D[n][l][r] >= 0)
    {
        return D[n][l][r];
    }
    if (D[n][l][r] == -1)
    {
        D[n][l][r] = 0;
    }
 
    D[n][l][r] = (go(n - 1, l - 1, r)%mod + go(n - 1, l, r - 1)%mod + (go(n - 1, l, r)*(n - 2))%mod);
 
    return D[n][l][r] %mod;
}
int main()
{
    int N, L, R;
    scanf("%d %d %d"&N, &L, &R);
    memset(D, -1sizeof(D));
    printf("%lld\n", go(N, L, R));
 
    return 0;
}
cs


반응형

'알고리즘 > BOJ' 카테고리의 다른 글

1720번  (0) 2017.12.29
2228번(다시..)  (0) 2017.12.29
2240번  (0) 2017.12.28
2410번  (0) 2017.12.28
2294번  (0) 2017.12.27