티스토리 뷰

BOJ

[BOJ] 18291 비요뜨의 징검다리 건너기

[gunwookim] 2020. 4. 13. 22:07

DP[N]:N번째 징검다리를 건널때 나올 수 있는 경우의 수 라고 잡아보면

DP[N]=DP[N1]+DP[N2]+...+DP[1] 이라는 식이 나오는데

DP[N1]=DP[N2]+DP[N3]+...+DP[1]

DP[N2]=DP[N3]+DP[N4]+...+DP[1]

                         .

                         .

                         .

 

DP[1]=1

이제 DP[1] 부터 DP[n1]DP[n] 의 식에 대입해 보면

DP[N]=21(DP[N2]+DP[N3]+...+DP[1])= 22(DP[N3]+DP[N4]+...+DP[1]) =23(DP[N4]+DP[N5]+...+DP[1])...=2N2DP[1] 가 나옵니다.

DP[1] = 1 이기 때문에 답은 2N2 가 됩니다.

각 테스트 케이스마다 2n2 구해주면 되지만 계속 2씩 곱하면 N이 최대 10억이기 때문에 시간이 터지게 됩니다. 그래서 분할정복으로 O(logN) 만에 구해야 합니다.

 

기본적으로 우리가 ab를 구하는 방법은 ab번 곱하는 방법입니다.

하지만 b가 짝수라면 ab/2 ab/2=ab, b가 홀수라면 ab/2ab/2a=b 임을 이용해보면 한번 곱할때마다 2배씩 줄어든다는 것을 알 수 있습니다. 이것을 활용해보면 O(logN) 만에 ab 를 구할 수 있습니다.

 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mpow(int x) {
    if(!x) return 1;
    ll tmp = mpow(x/2);
    return (tmp*tmp*(x % 2+1)) % 1000000007;
}
int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    int n,T;
    cin >> T;
    while(T--) {
        cin >> n;
        if(n == 1) cout << 1 << '\n';
        else cout << mpow(n-2) << '\n';
    }
}

 

'BOJ' 카테고리의 다른 글

[BOJ] 17302 흰색으로 만들기  (0) 2020.05.21
[BOJ] 2473 세 용액  (2) 2020.04.13
[BOJ] 13536 수열과 쿼리 4  (0) 2020.04.13
[BOJ] 1084 방 번호 2  (0) 2020.04.13
[BOJ] 18830 하이퍼 수열과 하이퍼 쿼리  (0) 2020.04.13
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/09   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함