1351. 무한 수열

2024. 4. 30. 14:22백준

문제 링크

 

1351번: 무한 수열

무한 수열 A는 다음과 같다.

A0 = 1

Ai = A⌊i/P⌋ + A⌊i/Q⌋ (i ≥ 1)

N, P와 Q가 주어질 때, AN을 구하는 프로그램을 작성하시오.

www.acmicpc.net

 

풀이

필요 지식: 다이나믹 프로그래밍, 재귀, 해시

 

해답을 구하기 위해 이전 번째 항의 값을 이용하니 DP를 활용하는 게 옳아 보인다. 그러나 N이 최대 1012이고, 메모리 제한도 128 MB이므로 0~1012번째 항까지 일일이 저장해 가며 푸는 방법은 불가능하다. 그렇다면 필요한 값만 저장해 뒀다 써야 할 것 같은데, 어떤 방식으로 해결해야 할까?

 

0번째 항부터 구해나가지 말고, N번째 항부터 나눠가는 방식을 생각해 보자. 주어진 식에 \(i=N\)을 대입하면

$$A_{N}=A_{\lfloor N/P \rfloor}+A_{\lfloor N/Q \rfloor}$$

이다. 그리고 \(A_{\lfloor N/P \rfloor}\)와 \(A_{\lfloor N/Q \rfloor}\) 역시 다음과 같이 나타낼 수 있다.

$$A_{\lfloor N/P \rfloor}=A_{\lfloor \lfloor N/P \rfloor /P \rfloor}+A_{\lfloor \lfloor N/P \rfloor / Q \rfloor}$$

$$A_{\lfloor N/Q \rfloor}=A_{\lfloor \lfloor N/Q \rfloor /P \rfloor}+A_{\lfloor \lfloor N/Q \rfloor / Q \rfloor}$$

뭔가 피보나치 수열처럼 재귀로 해결할 수 있을 것 같다. 실제로 \(A_{0}=1\)을 base condition으로 두고, 위 식을 바탕으로 하여 재귀함수 구현이 가능하다.

 

다만 N의 값의 크기와, 재귀의 특성으로 인한 실행 시간을 생각해야 한다. 재귀는 특성상 같은 함수를 여러 번 호출하므로 실행 시간을 많이 잡아먹는데, 특히 N/P = N/Q면 같은 값을 여러 번 계산하게 되므로 더욱 비효율적이다.

 

동일한 값을 여러 번 연산함으로 인한 함수 호출을 막기 위해, 구한 값을 별도의 자료구조에 저장할 것이다. 각 i번째 항에 대한 값은 유일하고, 정렬도 딱히 필요하지 않으므로 unordered_map 컨테이너에 i를 key로 하여 값을 저장한다. 이러면 해시 자료구조인 unordered_map 특성상 시간 복잡도는 \(O(1)\)이므로 탐색 속도도 빠르다.

 

시간 복잡도

\(P, Q\)의 값은 최소 2이므로, \(N/P, N/Q\)의 값은 항상 \(N\)보다 작은 값을 가진다. 그러므로 \(N\)이 커질수록 재귀호출의 깊이는 로그함수적으로 증가한다. 따라서 재귀함수의 시간 복잡도는 \(O(\log{N})\)이며, 해시로 이미 계산한 값을 저장하므로 실제로는 더 줄어든다.

 

소스코드

#include <iostream>
#include <unordered_map>
using namespace std;

long long N, P, Q;
unordered_map<long long, long long> um;

// 문제 해결을 위한 재귀함수
long long solve(long long num) {
    if(um.find(num) != um.end()) {
        return um[num];
    }
    else {
        long long A1 = solve(num / P), A2 = solve(num / Q);
        um.emplace(num, A1 + A2);
        return A1 + A2;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    
    cin >> N >> P >> Q;
    um.emplace(0, 1);
    
    cout << solve(N);
    return 0;
}

'백준' 카테고리의 다른 글

5373. 큐빙  (0) 2024.05.24
17281. ⚾  (0) 2024.05.08
20166. 문자열 지옥에 빠진 호석  (0) 2024.04.24
18869. 멀티버스 Ⅱ  (0) 2024.04.20
1309. 동물원  (1) 2024.04.11