BOJ 1309.동물원
문제 풀이 과정 및 느낀점(?)을 공유하고자 한다.
문제 출처
1. 문제설명
- 가로 2칸(고정), 세로 N칸
- 사자들을 우리에 가두고자 함.
- 가로, 세로 어디든 붙어 있게 배치할 수 없음.
- 배치할 수 있는 경우의 수는?
- 한 마리도 배치하지 않는 경우도 포함.
- 출력값은 9901로 나눈 나머지
2. 알고리즘 설계
- n이 입력되었을 때 가장 마지막 n-1번째에 들어올 수 있는 경우는 세 가지
- 사자를 배치하지 않음.
- 왼쪽에만 사자 배치
- 오른쪽에만 사자 배치
- n-2 번째
- n-1이 비워진 경우
- 이 경우에만 자기 자신의 케이스까지 올 수 있다.
- n-1이 왼쪽에 채워진 경우
- n-1이 오른쪽에 채워진 경우
- n-1이 비워진 경우
3. 로직
- 설계했던 부분을 2차원 DP로 구현하면 끝!
int dp[100001][3];
const int MOD = 9901;
dp[i][0] = (dp[i - 1][1] + dp[i - 1][2]) % MOD;
dp[i][1] = (dp[i - 1][0] + dp[i - 1][2]) % MOD;
dp[i][2] = (dp[i - 1][0] + dp[i - 1][1] + dp[i - 1][2]) % MOD;
4. 전체 코드
5. 소감
-
간단한 규칙을 찾은 풀이가 있었다.
#include <iostream> int D[100001]={1,3}; int main(){ int N; std::cin>>N; for(int i=2;i<=N;i++) D[i]=(D[i-1]*2+D[i-2])%9901; std::cout<<D[N]; }
- 위의 풀이는 간단하다고 생각하지만 좋은 풀이는아니라고 생각한다.
- 블로그 설명에는 케이스의 개수가 이러한 규칙이있다라고 표현되어 있다.
- 케이스의 개수가 조금 더 복잡한 규칙이었다면찾기 힘들었을 것이다.
- 간단한 DP 문제였지만, 규칙보다는 점화식을위한 접근이 더 중요하다고 느끼게 만든 문제였다.