본문 바로가기

백준

14002 가장 긴 증가하는 부분 수열 4

전까지 푼 LIS 문제가 단순히 길이를 구하는 문제였다면 이번 문제는 해당 수열까지 알아야 한다. 놀랍게도! 작년 알고리즘 수업 시간에 배운 개념이었어서 그걸 응용해서 풀 수 있었다. 

 

dp 배열에 최대 길이만 저장하는 게 아니라 자신의 이전 인덱스도 저장한다. 그래서 i번째 배열이 가장 긴 증가수열의 마지막이라 하면, 마지막부터 한 칸씩 되짚어본다. 그럼 해결~~~~

 

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <functional>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define xx first
#define yy second
#define all(x) (x).begin(), (x).end()
 
using namespace std;
using i64 = long long;
using ii = pair<int, int>;
using ii64 = pair<i64, i64>;
 
int main() {
    int n;
    scanf("%d", &n);
    
    vector<int> v(n+1);
    vector<ii> dp(n+1);
    for (int i = 1; i <= n; i++)
        scanf("%d", &v[i]);
        
    int max = 0;
    int maxi = 0;
    for (int i = 1; i <= n; i++)
    {
        if (dp[i].xx == 0)
            dp[i].xx = 1;
        for (int j = 1; j < i; j++)
        {
            if (v[i] > v[j])
            {
                if (dp[i].xx < dp[j].xx + 1)
                {
                    dp[i].xx = dp[j].xx + 1;
                    dp[i].yy = j;
                }
            }
        }
        
        if (max < dp[i].xx)
        {
            max = dp[i].xx;
            maxi = i;
        }
    }
    
    vector<int> ans;
    dp[0].yy = -1;
    
    ans.push_back(maxi);
    int tmp = dp[maxi].yy;
    while (dp[tmp].yy != -1)
    {
        ans.push_back(tmp);
        tmp = dp[tmp].yy;
    }

    printf("%d\n", max);
    for (int i = ans.size()-1; i >= 0; i--)
    {
        printf("%d ", v[ans[i]]);
    }
    
    return 0;
}

 

 

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

14911 궁합 쌍 찾기  (0) 2020.08.03
2022 사다리  (0) 2020.08.03
2565 전깃줄  (0) 2020.08.02
11053 가장 긴 증가하는 부분 수열  (0) 2020.08.02
1149 RGB거리  (0) 2020.07.31