알고리즘 문제 해결/BOJ

[LIS] BOJ 2568 전깃줄 - 2 (C++)

jmkimmessi 2022. 6. 21. 21:04
반응형

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

 

2568번: 전깃줄 - 2

첫째 줄에는 두 전봇대 사이의 전깃줄의 개수가 주어진다. 전깃줄의 개수는 100,000 이하의 자연수이다. 둘째 줄부터 한 줄에 하나씩 전깃줄이 A전봇대와 연결되는 위치의 번호와 B전봇대와 연결

www.acmicpc.net

 

문제 해결 알고리즘

 

LIS알고리즘에서 길이와 수열을 구하는 문제이다.

 

좀 달랐다면 여기서는 제거해야할 원소의 갯수와 위치를 출력한다는 점인데,

 

그 부분은 record 배열에서 LIS가 아닌 부분을 출력하면 그만인 문제이다.

 

아래의 링크에 자세한 설명이 있다.

 

https://kimmessi.tistory.com/191

 

[알고리즘] 최장 증가 부분 수열(LIS) - DP, 이분 탐색, LIS 출력

최장 증가 부분 수열 (LIS)이란? 어떤 수열에서 수열의 일부 원소를 골라 만든 부분 수열 중, 각 원소가 이전 원소보다 크다는 조건을 만족하고, 그 길이가 최대인 수열을 최장 증가 부분 수열이라

kimmessi.tistory.com

 

소스 코드

 

#include <bits/stdc++.h>
using namespace std;

int N;
int arr[500010], LIS[500010], record[500010];
int MAX = 0, MAX_num = 0, start_num = 500010;
stack<int> result;

int binary_search(int left, int right, int target){

    int mid;
 
    while(left < right){
 
        mid = (left + right) / 2;
 
        if(LIS[mid] < target) left = mid + 1;
        else right = mid;
 
    }
 
    return right;

}

int main(){
    ios::sync_with_stdio(0);
	cin.tie(0);

    cin >> N;

    for(int i=0;i<N;i++){
        int idx, num;
        cin >> idx >> num;

        MAX_num = max(MAX_num, idx);
        start_num = min(start_num, idx);

        arr[idx] = num;
    }

    int j = 1, i = start_num+1;
    LIS[1] = arr[start_num];
    record[start_num] = 1;

    while(i <= MAX_num){

        if(LIS[j] < arr[i]){
            LIS[++j] = arr[i];
            record[i] = j;
        }
        else{
            if(arr[i] == 0)  record[i] = 0;
            else{
                int idx = binary_search(1, j, arr[i]);
                LIS[idx] = arr[i];

                record[i] = idx;
            }
        }

        MAX = max(MAX, record[i]);
        i++;
    }


    for(int i=MAX_num;i>0;i--){
        if(record[i] == 0) continue;

        if(MAX == record[i]) MAX--;
        else result.push(i);
    }

    cout << result.size() << '\n';

    while(!result.empty()) {
        cout << result.top() << '\n';
        result.pop();
    }

}
반응형