ps(알고리즘)
가장 긴 증가하는 부분 수열 2
bluesunset
2024. 6. 26. 16:19
dp로 풀려고 했는데 시간복잡도가 제곱이라 안될거 같아서 이분 탐색을 써야겠다는 생각이 들었다.
수열을 앞에서부터 읽으면서 가장 긴 증가하는 부분 수열 lis라는 배열을 따로 만들어서 값을 채워간다.
수열의 값이 lis의 마지막 값, 즉 가장 큰 값보다 더 크면 lis의 크기를 늘리고 맨 뒤에 추가시켜준다.
lis의 마지막 값보다 크지 않을 때는 수열의 값이 lis 배열 내에서 어디 위치해야 하는지 이분탐색으로 찾아주고, 대체해준다.
예를 들어서 10 20 40 이 있는 경우에 15가 들어오면 15는 10과 20 사이인데 20을 대체해서 10 15 40으로 만들어준다.
#include<stdio.h>
int N,ans;
int lis[1000004];
int pos(int s, int e, int v)
{
if(s==e) return s;
int mid = (s+e)/2;
if(lis[mid]<v){
return pos(mid+1,e,v);
}
else{
return pos(s,mid,v);
}
}
int main()
{
scanf("%d",&N);
for(int i=1;i<=N;i++){
int a;
scanf("%d",&a);
if(ans==0){
ans=1;
lis[ans]=a;
}
else{
if(lis[ans]<a){
ans++;
lis[ans]=a;
}
else{
int x = pos(1,ans,a);
lis[x]=a;
}
}
}
printf("%d",ans);
}
이분탐색 구현은 그냥 하면 되고 전체 해결 코드이다.