반응형
동적 계획법
2747번: 피보나치 수 (acmicpc.net) 피보나치는 수는 0과 1로 시작하며 2번째 부터는 앞의 두 수를 더해서 이어 나갑니다.즉 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 --------으로 이어집니다. N번째 피보나치 수
flrjtwjrjt.tistory.com
2 * N 크기의 직사각형을 1 * 2, 2 * 1 크기의 타일로 채우는 방법의 수를 구하는 문제입니다.
이런 문제는 항상 패턴을 분석하는 것을 먼저 해야 합니다.
풀이법
우선 예시를 그려보겠습니다.
⌈ ⌉
⌊ ⌋ , [ㅡㅡ]
N = 1
⌈ ⌉
⌊ ⌋ 1개
N = 2
⌈ ⌉⌈ ⌉ [ㅡㅡ]
⌊ ⌋⌊ ⌋, [ㅡㅡ] 2개
N = 3
⌈ ⌉⌈ ⌉⌈ ⌉ ⌈ ⌉ [ㅡㅡ] [ㅡㅡ]⌈ ⌉
⌊ ⌋⌊ ⌋⌊ ⌋, ⌊ ⌋ [ㅡㅡ], [ㅡㅡ]⌊ ⌋ 3개
N = 4
⌈ ⌉⌈ ⌉⌈ ⌉⌈ ⌉ ⌈ ⌉⌈ ⌉[ㅡㅡ] ⌈ ⌉[ㅡㅡ]⌈ ⌉ [ㅡㅡ]⌈ ⌉⌈ ⌉ [ㅡㅡ][ㅡㅡ]
⌊ ⌋⌊ ⌋⌊ ⌋⌊ ⌋, ⌊ ⌋⌊ ⌋[ㅡㅡ], ⌊ ⌋[ㅡㅡ]⌊ ⌋, [ㅡㅡ]⌊ ⌋⌊ ⌋, [ㅡㅡ][ㅡㅡ] 5개
어떻게 채워야 할지는 감이 안오지만 개수에서 패턴이 하나 보이네요
N이 3일 때의 타일을 채우는 경우의 수 = N이 2일 때 경우의 수 + N이 1일 때 경우의 수
N이 4일 때의 타일을 채우는 경우의 수 = N이 3일 때 경우의 수 + N이 2일 때 경우의 수
즉
D[i] = D[ i - 1 ] + D[ i - 2 ]
라는 조합식을 생각해 볼 수 있겠습니다.
정답 코드
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
D.resize(N + 1);
D[1] = 1;
D[2] = 2;
for (int i = 3; i <= N; i++) {
D[i] = (D[i - 1] + D[i - 2]) % 10007;
}
cout << D[N];
}
톱-다운 방식으로 구현한다면 아래 처럼 할 수 있겠습니다.
long Function(int id)
{
if (D[id] > 0)
return D[id];
return D[id] = (Function(id - 1) + Function(id - 2) ) % 10007;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> N;
D.resize(N + 1);
D[1] = 1;
D[2] = 2;
cout << Function(N);
}
반응형
LIST
'알고리즘 문제 > 백준' 카테고리의 다른 글
13398 연속합2 (동적계획법) [Gold V] (0) | 2024.05.07 |
---|---|
10844 쉬운 계단 수 (동적계획법) [Silver I] (0) | 2024.05.06 |
2193 이친수 (조합론, 동적 계획법) [Silver III] (0) | 2024.05.04 |
1463 1로 만들기 (동적 계획법) [Silver III] (2) | 2024.05.03 |
2747 피보나치 수 (동적계획법)[Bronze II] (0) | 2024.05.02 |