BOJ 2038 - 골롱 수열
문제
Golomb 수열의 임의의 항을 구하는 문제이다. Golomb 수열은 임의의 \(k\)에 대해 \(k\)가 수열상에서 \(f(k)\)번 등장하는 단조증가 수열이다.
\(1\le n \le 2,000,000,000\)일 때 \(f(n)\)을 구해야 한다.
풀이
수열의 정의대로 \(i\)를 증가시켜 정확히 \(f(n)\)을 구하려고 하면 \(n\)의 범위 때문에 메모리 초과가 난다.
Golomb 수열의 점화식은 아래와 같다.
\[f(n+1)=1+f(n+1-f(f(n)))\]이 점화식을 사용해서 dp를 구성하면 된다.
이때 \(i\)번째에 대해 \(\sum{f(i)}\)개의 항이 결정된 상태이기 때문에 수열의 합이 \(n\)을 넘는 시점의 \(i\)가 \(f(n)\)의 값이 된다.
소스코드
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
#include<iostream>
#include<vector>
#include<utility>
#include<algorithm>
using namespace std;
using pii=pair<int, int>;
using vi=vector<int>;
using lld=long long;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n, filled, i;
vi a(4000000, 0);
cin>>n;
i=1;
a[1]=1;
filled=1;
while(filled<n){
i++;
a[i]=1+a[i-a[a[i-1]]];
filled+=a[i];
}
cout<<i;
return 0;
}
풀고나서
- 점화식을 스스로 구해보려고 했는데 어려웠다.
Leave a comment