알고리즘/백준 알고리즘

백준 1904번 01타일[C++]

빠켱이 2020. 9. 1. 14:49

1904번 문제는 문제를 보고 규칙이 생각나지 않았습니다. 그래서 DP문제이므로 N값에 대한 결과 값을 나열해보았더니 규칙을 찾았습니다.

DP문제를 푸는 방법 중에 생각이 풀이 방법이 생각이 나지 않는다면 값을 나열하며 결과 값 수열의 규칙을 찾는 것도 좋은 방법인 것 같습니다.

나열을 해보니

N = 1 >> 1 -> 1가지

N = 2 >> 00, 11 -> 2가지

N = 3 >> 100, 001, 111 ->3가지

N = 4 >> 0000, 1100, 1001, 0011, 1111 -> 5가지

N = 5 >> 10000, 00100, 00001, 11100, 11001, 10011, 00111, 11111 -> 8가지

까지 구해봤는데 숫자들이 익숙해서 N = 6인 경우를 구해봤더니 13가지였습니다. 이 패턴은 피보나치의 패턴과 같기도 하였습니다.

따라서

0값이 0

1 값이 1

2 값이 2까지 설정한 후

점화식을 새우면 dp [i] = dp [i-1] + dp [i-2]라는 수식이 만들어졌습니다.

#include <iostream>
#include <vector>
using namespace std;
vector<long long> v;
int main(){
    int n;
    scanf("%d", &n);
    v.push_back(0);
    v.push_back(1);
    v.push_back(2);
    for(int i = 3; i <= n; i++){
        v.push_back((v[i-1]+v[i-2])%15746);
    }
    printf("%d", v[n]);
    return 0;
}

이문제의 실수 요인으로는 15746으로 나눈 값의 나머지를 출력하라고 해서 마지막 결과 값에 %15746만 추가 연산을 하는 경우가 있을 수 있는데 N값이 충분히 커졌을 때 이미 중간에서 long long의 허용범위를 넘어서는 값이 발생할 수도 있기 때문에 애초에 값을 저장할 때 % 연산을 통해 값을 저장해주었습니다(더해서 나머지를 구하나 나머지끼리 더해서 구하나 연산 값은 같음)