Post

[백준 C++] 1309번 동물원

백준 1309번 동물원 c++로 풀이

[백준 C++] 1309번 동물원

1309번: 동물원

문제 요약

문제

어떤 동물원에 가로로 두칸 세로로 N칸인 아래와 같은 우리가 있다.

이 동물원에는 사자들이 살고 있는데 사자들을 우리에 가둘 때, 가로로도 세로로도 붙어 있게 배치할 수는 없다. 이 동물원 조련사는 사자들의 배치 문제 때문에 골머리를 앓고 있다.

동물원 조련사의 머리가 아프지 않도록 우리가 2*N 배열에 사자를 배치하는 경우의 수가 몇 가지인지를 알아내는 프로그램을 작성해 주도록 하자. 사자를 한 마리도 배치하지 않는 경우도 하나의 경우의 수로 친다고 가정한다.

사용 알고리즘

다이나믹 프로그래밍

입출력

  • 입력: 첫째 줄에 우리의 크기 N(1≤N≤100,000)이 주어진다.
  • 출력: 첫째 줄에 사자를 배치하는 경우의 수를 9901로 나눈 나머지를 출력하여라. ``` 예제1

입력 4 출력 41

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
## 풀이
최대값이나 최소값을 사용하지 않는 dp 문제이다. 사자의 개수를 0개 부터 쭉 넣는다고 할때 사자를 넣는 조합의 개수를 구하면 된다. 맨 윗줄부터 차근차근 넣는다고 생각하면 첫줄에는 모두 안 넣는 경우, 왼쪽에 한 마리 넣는 경우, 오른쪽에 한 마리 넣는 경우 총 3가지 경우가 있다. 모두 넣는 경우는 조건에 맞지 않는다. 다음 두번째 줄에는 윗줄의 세 경우를 이용하여 구할 수 있다. 두 번째 줄에 모두 안 넣는 경우는 윗줄에서 어떤 조합을 하든 가능하므로 모두 더해서 구한다. 왼쪽이나 오른쪽의 경우 모두 안넣는 경우와 반대쪽에만 넣은것을 더해서 구할 수 있다. for문으로 반복하고 9901을 나눠서 나머지를 구해서 한다.

## 어려웠던 점


## 배운 점 / 느낀 점
왼쪽에 넣는 경우와 오른쪽에 넣는 경우가 어차피 같으므로 하나로 합치면 속도나 메모리가 더 좋아지겠지만 나눠서 해도 통과될거 같아서 하나로 했다. 하나로 합쳐서도 해 보고 싶다.

## 전체 코드
```cpp
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int n;
vector<vector<int>> dp;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);

    cin >> n;
    dp = vector<vector<int>>(n, vector<int>(4));
    dp[0] = {1,1,1};
    for(int i = 1; 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];
        dp[i][0] %= 9901;
        dp[i][1] %= 9901;
        dp[i][2] %= 9901;
    }
    cout << (dp[n-1][0]+dp[n-1][1]+dp[n-1][2])%9901;

    return 0;
}
This post is licensed under CC BY 4.0 by the author.