반응형
Notice
Recent Posts
Recent Comments
Link
«   2024/07   »
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 31
Archives
Today
Total
관리 메뉴

코딩하기 좋은날

백준 14003 가장 긴 증가하는 부분 수열5 본문

백준(Baekjoon) 문제

백준 14003 가장 긴 증가하는 부분 수열5

huiung 2019. 9. 5. 08:00
반응형

https://www.acmicpc.net/problem/14003

문제와 채점은 위 사이트에서 확인 하실 수 있습니다.

 

가장 긴 증가하는 부분 수열의5번째 문제입니다. LIS의 길이와 그 수열을 직접 출력해야 합니다.

 

N이 100만이므로 lower_bound를 이용하여 O(NlogN)의 시간이 걸리는 방법으로 LIS의 길이를 먼저 구합니다.

 

lower_bound를 이용하여 구한 dp배열원소는 실제 수열이 아니므로 실제 수열을 구하기 위해서

 

pair배열을 하나 둔다음 각각 반복문을 돌때마다 dp배열에서 해당하는 동작을 하는 ind와 그 값을 저장해 줍니다.

 

이후 pair 배열을 끝에서 부터 역추적하면서 수열을 찾아주면 됩니다. 예를 들어 수열의 길이가 4라면

 

pair배열의 끝에서부터 확인하며 ind가 3인값이 처음나오면 그 값이 LIS수열의 마지막 원소가 됩니다. 스택에 집어넣고 ind값을 1줄이고 다시 돌면서 ind가 2인값이 처음나올때를 push하면서 끝까지 돌면 LIS수열을 구할 수 있습니다.

 

다음은 코드입니다.

 

#include <iostream>
#include <stack>

using namespace std;

int arr[1000001];
int ind = 0;
int dp[1000001];
pair<int,int> p[1000001];

int main(void) {
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    stack<int> ans;
    int N; cin >> N;
    for(int i = 0; i < N; i++) {
        cin >> arr[i];
        if(i == 0) {
            dp[ind] = arr[i];
            p[i] = make_pair(ind, arr[i]);
        }
        else if(dp[ind] < arr[i]) {
            dp[++ind] = arr[i];
            p[i] = make_pair(ind, arr[i]);
        }
        else {
            int it = lower_bound(dp, dp+ind, arr[i]) - dp;
            dp[it] = arr[i];

            p[i] = make_pair(it, arr[i]);
        }
    }
    cout<<ind+1<<'\n';

    int cp = ind;
    for(int i = N-1; i >= 0; i--) {
        if(p[i].first == cp) {
            ans.push(p[i].second);
            cp--;
        }
    }

    while(!ans.empty()){
        cout<<ans.top()<<' ';
        ans.pop();
    }
    return 0;
}

 

 

 

 

반응형

'백준(Baekjoon) 문제' 카테고리의 다른 글

백준 7569 토마토  (0) 2019.09.16
백준 16500 문자열 판별  (0) 2019.09.05
백준 8979 올림픽  (0) 2019.09.05
백준 2935 소음  (0) 2019.09.05
백준 4195 친구 네트워크  (0) 2019.08.11