정리와기록 블로그

[2193] 이친수 본문

BOJ/동적계획법

[2193] 이친수

뫂림 2020. 3. 7. 15:06

문제: 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

 

접근:

  • 1만 연속으로 못 붙이는 것을 감안하여, 재귀함수를 int getNum(int i, int last) 라고 만들었다. 여기서 last는 마지막에 붙는 수이다.
  • 마지막 수가 1인 경우와 0인 경우를 나누어서 함수를 호출하면 된다.
  • 첫 함수 호출 시, 1로 시작하는 것을 신경쓴다.

 

코드:

#include <iostream>
#include <memory.h>

using namespace std;

typedef long long dl;
int N;
dl cache[91][2];
// i부터 N까지의 이친수를 만들고 그 개수를 반환함
dl getPnum(int i, int last)
{
	if (i == N) return 1;

	dl& ret = cache[i][last];
	if (ret != -1) return ret;

	if (last == 1) return ret = getPnum(i + 1, 0);
	return ret = getPnum(i + 1, 1) + getPnum(i + 1, 0); // 1로 이어나가거나, 0으로 이어나가거나
}

int main()
{
	ios::sync_with_stdio(false);
	memset(cache, -1, sizeof(cache));
	cin >> N;
	// 첫번째 수는 반드시 1로 시작한다
	cout << getPnum(1, 1) << "\n";
	return 0;
}

'BOJ > 동적계획법' 카테고리의 다른 글

[14002] 가장 긴 증가하는 부분 수열 4  (0) 2020.03.07
[9465] 스티커  (0) 2020.03.07
[16194] 카드 구매하기 2  (0) 2020.03.05
[15990] 1, 2, 3 더하기 5  (0) 2020.03.05
[15988] 1, 2, 3 더하기 3  (0) 2020.03.04
Comments