본문 바로가기
Problem Solving

[BOJ 2193] 이친수

by Ladun 2020. 1. 13.

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

 

2193번: 이친수

0과 1로만 이루어진 수를 이진수라 한다. 이러한 이진수 중 특별한 성질을 갖는 것들이 있는데, 이들을 이친수(pinary number)라 한다. 이친수는 다음의 성질을 만족한다. 이친수는 0으로 시작하지 않는다. 이친수에서는 1이 두 번 연속으로 나타나지 않는다. 즉, 11을 부분 문자열로 갖지 않는다. 예를 들면 1, 10, 100, 101, 1000, 1001 등이 이친수가 된다. 하지만 0010101이나 101101은 각각 1, 2번 규칙에 위배되

www.acmicpc.net


이 문제는 의외로 단순하게 풀 수 있다.

 

길이가 N인 이친수의 개수를 구하는 것은 길이가 N - 1인 이친수에서 0으로 끝나는 이친수와 1로 끝나는 이친수를 찾아서 계산하면 된다.

 

이친수는 0으로 시작하지 않기 때문에 길이가 1인 이친수는 1개이다.

 

이친수는 11인 부분이 존재하지 않는다.

 

즉, N - 1인 이친수에서 1로 끝나는 이친수에는 0을 붙이고,

 

0으로 끝나는 이친수에는 0, 1을 둘 다 붙여서 생긴 이친수의 개수가 정답이 된다.

 

길이가 N인 이친수에서 0으로 끝나는 것의 개수 + 1로 끝나는 것의 개수 = 길이가 N인 이친수의 개수이다.

 

길이가 1 ~ N까지 순차적으로 0과 1로 끝나는 것의 개수를 구하면 된다.

 

예를 들어 

N = 1, 1

N = 2, 10

N = 3, 101 100

N = 4, 1010 1001 1000

N = 5, 10101 10100 10010 10001 10000

.....

 

위 예제를 보면

 

N의 0의 개수 = (N - 1)의 1의 개수 + (N - 1)의 0의 개수

N의 1의 개수 = (N - 1)의 0의 개수

 

이다!


#include <stdio.h>


unsigned long long int dp[91][2];
int main()
{

	int N;

	scanf("%d", &N);
	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];
	}
	printf("%lld", dp[N][0] + dp[N][1]);
	return 0;
}

'Problem Solving' 카테고리의 다른 글

[BOJ 15685] 드래곤 커브  (0) 2020.03.25
[BOJ 14891] 톱니바퀴  (0) 2020.03.25
[BOJ 1932] 정수 삼각형  (0) 2020.01.13
[BOJ 2884] 알람 시계  (0) 2020.01.03
[BOJ 1924] 2007년  (0) 2020.01.03