less than 1 minute read

[no-alignment]

구현 방식

  • 아래의 사진과 같이 i 번째 자리는 i - 1 번째에서 나올 수 있는 이진 수에서 0 또는 1 을 끝에 붙여서 만들 수 있다.

[no-alignment]

  • 다만 맨 끝자리가 1로 끝난 경우에는 끝에 0 만 붙일 수 있고, 0 으로 끝났을 때는 0 과 1 둘다 올 수 있다.
  • 즉, i - 1 번째에서 0 으로 끝난 이진수의 개수를 a 개 1 로 끝난 이진수의 개수를 b개라고 했을 때
  • i 번째에서 0으로 끝난 이진수의 개수는 a + b 개, 1로 끝난 이진수의 개수는 a 개 이다.
  • 이를 점화식으로 나타내면 아래와 같다.
acc[i].endZERO = acc[i-1].endZERO + acc[i-1].endONE
acc[i].endONE = acc[i-1].endZERO

코드

  • 코드는 아래와 같다. 튜플을 이용해서 first 에는 0으로 끝나는 이진수의 개수를, second 에는 1로 끝나는 이진수의 개수를 담았다.
long long DP(int N)
{
    // first : 0으로 끝나는 이진수의 개수 , second : 1로 끝나는 이진수의 개수
    vector<pair<long long, long long>> acc = vector<pair<long long, long long>>(N + 1);
    acc[1] = { 0 , 1 }; // 1 한개

    for (int i = 2; i <= N; i++)
    {
        acc[i] = { acc[i - 1].first + acc[i - 1].second, acc[i - 1].first };
    }

    return acc[N].first + acc[N].second;
}