알고리즘/BOJ

[BOJ] 백준 2193번: 이친수

벨에삐 2023. 2. 26. 04:45

https://www.acmicpc.net/problem/2193

 

2193번: 이친수

0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 중 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다. 이친수는 0으로 시작하지 않

www.acmicpc.net

 

이번에도 DP 기본 문제입니다.

 

#include <bits/stdc++.h>
#define ll long long
using namespace std;

int N;
ll dp[91][2];

void solve(){
	dp[1][0] = 0;
	dp[1][1] = 1;
	
	for(int i = 2; i <= N; ++i){
		dp[i][0] = dp[i-1][0] + dp[i-1][1];
		dp[i][1] = dp[i-1][0]; 
	}
	
	cout << dp[N][0] + dp[N][1];
}

int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	cin >> N;
	
	solve();
}

 

항상 같은 패턴입니다. dp 문제는 1) table 정의 2) 점화식 찾기 3) 초기값 설정의 3단계로 풀이합니다.

 

1) table 정의

dp[i][k] : k로 끝나는 i자리 이친수의 개수(k = 0, 1)

 

2) 점화식 찾기

dp[i][0] = dp[i-1][0] + dp[i-1][1];
dp[i][1] = dp[i-1][0]; 

 

3) 초기값 설정
dp[1][0] = 0;
dp[1][1] = 1;

 

이친수에서는 1이 두 번 연속으로 나타나지 않는다는 제약 조건으로 인해 2차원 table을 정의하여 점화식을 세웠고,

이친수는 0으로 시작하지 않는다는 성질은 초기값 설정에서 dp[1][0] = 0 으로 설정해주면 만족하게 됩니다.

 

주의할 점은 N이 90으로 작더라도 90자리 이친수의 개수는 2880067194370816120개로 매우 많습니다.

dp 배열의 자료형을 int로 할 경우 integer overflow가 발생하므로 잘못된 답을 출력하게 됩니다.

경계조건 코너 케이스에 유의하여 미리 임의의 테스트케이스를 만들어 값을 넣어볼 필요가 있습니다.

이 문제의 경우 최악의 경우에도 이친수의 개수가 long long의 범위 안에 있으므로 long long 자료형을 사용하면 되지만, 종종 long long 의 범위를 넘어가는 문제가 있는데 그럴 때에는 string이나 vector를 이용해 큰 수(big integer)의 연산을 구현해야 합니다. 다만 이런 경우에는 대부분 문제에서 주어진 값으로 나눈 나머지를 출력하도록 문제가 구성됩니다.

 

시간복잡도 O(N)입니다.

'알고리즘 > BOJ' 카테고리의 다른 글

[BOJ] 백준 11726번: 2×n 타일링  (0) 2023.02.26
[BOJ] 백준 1904번: 01타일  (0) 2023.02.26
[BOJ] 백준 2294번: 동전 2  (0) 2023.02.26
[BOJ] 백준 9465번: 스티커  (0) 2023.02.26
[BOJ] 백준 1463번: 1로 만들기  (0) 2023.02.26