※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 13912번 문제인 외계 생물이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/13912
13912번: 외계 생물
기문이는 특이한 외계 생물을 한 마리 발견하였다. 발견될 때에는 갓 태어난 상태였다. 이 생물은 태어난 지 하루가 지나면 정확히 두 명의 새끼를 낳는데, 한번 새끼를 낳고 나면 그 이후로는
www.acmicpc.net
H일째의 외계 생물 2^(H+1) - 1 마리에게 이름을 붙여보자. 이를 dp[H]라 하겠다.
맨 처음에 새끼를 낳은 외계 생물은 유일하고, 해당 생물이 1번 번호를 달아야 함은 자명하다.
1번 번호의 생물은 두 마리의 새끼를 낳을 것이고, 각 새끼는 남은 H-1일동안 2^H - 1마리의 외계 생물을 생산해내게 될 것이다. 각 2^H - 1마리에게 달 번호로 사용할 수의 집합이 정해지면, 2^H - 1마리들에게 번호가 달릴 경우의 수는 dp[H-1]과 같게 됨을 관찰할 수 있다. 따라서 dp[H] = choose(2^(H+1) - 2, 2^H - 1) * dp[H-1]^2 로 계산할 수 있게 된다.
위 계산에 필요한 조합값은 O(N^2)에 미리 전처리해 구해두자.
아래는 제출한 소스코드이다.
#include <iostream>
using namespace std;
typedef long long ll;
int choose[2049][2049];
void combinit() {
for (int n = 1; n < 2049; n++) {
choose[n][0] = 1;
for (int i = 1; i < n; i++) {
int& cur = choose[n][i];
cur = choose[n - 1][i - 1] + choose[n - 1][i];
if (cur > 1000000006) cur -= 1000000007;
}
choose[n][n] = 1;
}
}
ll ans[11];
void solve() {
ans[0] = 1;
for (int i = 1; i < 11; i++) {
int tmp = (1 << (i + 1)) - 2;
ans[i] = (choose[tmp][tmp / 2] * ((ans[i - 1] * ans[i - 1]) % 1000000007)) % 1000000007;
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
combinit();
solve();
int H; cin >> H;
cout << ans[H];
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 13902 // C++] 개업 2 (0) | 2023.03.28 |
---|---|
[BOJ 13901 // C++] 로봇 (0) | 2023.03.27 |
[BOJ 13911 // C++] 집 구하기 (0) | 2023.03.25 |
[BOJ 13903 // C++] 출근 (0) | 2023.03.24 |
[BOJ 13910 // C++] 개업 (0) | 2023.03.23 |