문제출처: https://www.acmicpc.net/problem/1309
문제
어떤 동물원에 가로로 두칸 세로로 N칸인 아래와 같은 우리가 있다.
이 동물원에는 사자들이 살고 있는데 사자들을 우리에 가둘 때, 가로로도 세로로도 붙어 있게 배치할 수는 없다. 이 동물원 조련사는 사자들의 배치 문제 때문에 골머리를 앓고 있다.
동물원 조련사의 머리가 아프지 않도록 우리가 2*N 배열에 사자를 배치하는 경우의 수가 몇 가지인지를 알아내는 프로그램을 작성해 주도록 하자. 사자를 한 마리도 배치하지 않는 경우도 하나의 경우의 수로 친다고 가정한다.
입력
첫째 줄에 우리의 크기 N(1≤N≤100,000)이 주어진다.
출력
첫째 줄에 사자를 배치하는 경우의 수를 9901로 나눈 나머지를 출력하여라.
풀이
이 문제를 dp로 풀어야겠다고 생각한분들 대단합니다.. 단순히 배열에 값 넣어서 규칙에맞게 푸는줄알았는데 절대안되더군요 그리고 규칙을 찾으려해도 이미 보기에서 4일때 41이라서 직접규칙을 찾을 엄두도안났네요.. 그래서 dp로 답을구한분들의 풀이를 참고하였습니다. dp인걸 알고나서는 dp연산을위한 배열선언 -> 초기값 설정 ,, 이 두 가지가 기본이잖아요? 어려웠던 부분은 dp[n][2]가 아닌 dp[n][3]으로 선언해야한다는 것입니다.
초기값설정을 위해 규칙을 알아봅시다. n=1일때, 총3가지경우가 나옵니다.(호랑이가 없을 때, 왼쪽에 호랑이 있을 떄, 오른쪽에 있을 때) 각각의 경우를 1로(다 가능한 경우이므로 0이아닌 참값으로설정) 초기화 하고 n=2일떄,n=3일떄.... 의 경우의수를 구하면됩니다. 위에서 언급한 3가지의 케이스를 이용하여 각각의 경우에 대해 가능한 경우의수를 담아야합니다. dp배열을 선언하는 것과 이 연산의 식 세우기가 어렵습니다.
결론적으로, dp[n][0]+dp[n][1]+dp[n][2]는 2*n공간에서 호랑이를 배열할 수 있는(호랑이가없는경우도 하나의경우로포함됨) 모든경우의 수 입니다.
코드
#include<iostream> using namespace std; int dp[100001][3]; //arr[x][0]=x층 아무도없을 떄 //arr[x][1]=x층 왼쪽에 호랑이O //arr[x][2]=x층 오른쪽에 호랑이O int main() { int n; cin >> n; //n=1일때 ==초기값설정 //n=1일때 3가지경우이므로 각 경우 1로설정 dp[1][0] = dp[1][1] = dp[1][2] = 1; for (int i = 2; i <= n; i++) { dp[i][0] = (dp[i - 1][0] + dp[i - 1][1] + dp[i - 1][2]) % 9901; dp[i][1] = (dp[i - 1][0] + dp[i - 1][2]) % 9901; dp[i][2] = (dp[i - 1][0] + dp[i - 1][1]) % 9901; } cout << (dp[n][0] + dp[n][1] + dp[n][2]) % 9901 << endl; }
결과
'문제풀이(BOJ) > 다이나믹 프로그래밍' 카테고리의 다른 글
[백준 16395] 파스칼의 삼각형 (0) | 2020.03.10 |
---|---|
[백준 11055] 가장 큰 증가 부분수열 (0) | 2020.03.09 |
[백준 1010] 다리 놓기 (0) | 2019.12.11 |
[백준 11052] 카드 구매하기 (0) | 2019.12.11 |
[백준 1912] 연속합 (0) | 2019.12.08 |