백준 No.1904 [01타일]
본문 바로가기
Algorithm (C++ based)/BOJ

백준 No.1904 [01타일]

by 조훈이 2020. 11. 6.

// Baekjoon Online Judge No.1904 [01 타일]


   How to solve   

  복잡할 것 같아 보이지만 N에 1, 2, 3 ... 8 까지만 대입 해보아도 결국 피보나치수열을 이룬다는 것을 알 수 있다.

하지만 이 문제에서 고려해야하는 점이 두 가지 있다.

 1. 피보나치 수열을 구하는 함수를 구현할 때 1,000,000번째 항까지 구해야 하므로
     Time out 이 생기지 않을 방법으로 함수를 구현하여야 한다.

 2. 아무리 unsigned long long 자료형을 가진다고 해도 1,000,000번째 피보나치수는 overflow를 발생시킨다.

"1. 피보나치 수열을 구하는 함수를 구현할 때 1,000,000번째 항까지 구해야 하므로
     Time out 이 생기지 않을 방법으로 함수를 구현하여야 한다."

  만약 <Recursive function>으로 피보나치 수열을 구하는 함수를 구현한다면, 결국 호출된 함수의 개수가 기하급수적으로 늘어나 결국 Time out이 발생할 것이다.

  아래 코드를 보면 알 수 있듯, <Dynamic Programming (동적 계획)>을 이용하여 구현한다면 Time out없이 구현할 수 있다. 물론, <Dynamic programming>의 특성상 불필요한 Memory의 소모가 있긴 하겠지만!

 

"2. 아무리 unsigned long long 자료형을 가진다고 해도 1,000,000번째 피보나치수는 overflow를 발생시킨다."

  피보나치 수열의 100번째 항의 값만 해도 354,224,848,179,261,915,075가 되고 이 숫자는 unsigned long long 자료형의 최대값인 18,446,744,073,709,551,615를 넘는다. 그렇다면 1,000,000번째 항의 값은 상상도 못 할 만큼 큰 숫자일 것이다. 따라서 unsigned long long의 자료형을 가지는 answer vector에는 피보나치 값을 그대로 넣지 못할것이다.

 

  우리는 결국 answer[N]을 15,746으로 나눈 나머지를 출력해야하기 때문에 answer[N]에 N번째 피보나치 수를 15,746으로 나눈 값을 넣는 것은 어떨까? 하는 생각을 가져볼 수 있다. 아래의 코드처럼 말이다. 아래 코드를 보면 answer[i - 1] % 15746 + answer[i - 2] % 15746answer[i]의 값에 넣는것을 볼 수 있다.

 

  (answer[i - 1+ answer[i - 2]) % 15746 를 생각할 수도 있겠지만 (a + b) % c 의 값과 a % c + b % c의 값은 항상 같은건 아니라 이렇게는 쓰일 수 없다.


반례 : a = 3, b = 3, c = 2


(3 + 3) % 2 == 0
3 % 2 + 3 % 2 == 1

 

  마지막에 정답을 출력할 때엔 answer[N]이 아닌 answer[N] % 15746를 출력해야 한다.

  answer[N - 1] % 15746 + answer[N - 2] % 15746 의 값이 15,746보다 클 수가 있기때문에 answer[N] % 15746를 출력해야 한다는 것을 알 수 있을 것이다.


   Code   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <vector>
 
using namespace std;
 
int N;
vector<unsigned long long> answer(1000001);
 
int main() {
    answer[0= 1;
    answer[1= 1;
 
    for (int i = 2; i <= 1000000; i++) {
        answer[i] = answer[i - 1] % 15746 + answer[i - 2] % 15746;
    }
    
    cin >> N;
 
    cout << answer[N] % 15746;
}
cs

 


※ 아직 운영 준비중인 블로그 입니다.

728x90

'Algorithm (C++ based) > BOJ' 카테고리의 다른 글

백준 No.10757 [큰 수 A+B]  (0) 2021.01.05
백준 No.10844 [쉬운 계단 수]  (0) 2020.11.18
백준 No.1932 [정수 삼각형]  (0) 2020.11.16
백준 No.1149 [RGB거리]  (0) 2020.11.10
Dynamic programming (동적 계획)  (0) 2020.11.09

댓글