Home [14002] 가장 긴 증가하는 부분 수열 4
Post
Cancel

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

문제 링크 : https://www.acmicpc.net/problem/14002

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

본문

수열 $A$가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오.

예를 들어, 수열 $A = \lbrace 10, 20, 10, 30, 20, 50 \rbrace$ 인 경우에 가장 긴 증가하는 부분 수열은 $A = \lbrace $ 10, 20, 10, 30, 20, 50 $\rbrace$ 이고, 길이는 4이다.

입력

첫째 줄에 수열 $A$의 크기 $N$ ($1 \leq N \leq 1000$)이 주어진다.

둘째 줄에는 수열 $A$를 이루고 있는 $A_i$가 주어진다. ($1 \leq A_i \leq 1000$)

출력

첫째 줄에 수열 $A$의 가장 긴 증가하는 부분 수열의 길이를 출력한다.

제한

시간 제한메모리 제한
1sec256MB

풀이

LIS 기본 문제이다. 풀이는 참고로 대체.

코드

사용 언어 : C

최종 수정일 : 2023 / 3 / 19

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <stdio.h>

typedef struct Node {
    int v;
    int idx;
} ND;

#define MAX_IDX 1001
const int START = 0;
const int END = -1;

int arr[MAX_IDX];

ND LIS[MAX_IDX];
int lis[MAX_IDX];
int pre[MAX_IDX];
int lis_len;
int lis_cur;
int n;

int lower_bound(int x) {
    int s = 0, e = lis_len + 1;
    int mid;

    while (s < e) {
        mid = (s + e) / 2;

        if (LIS[mid].v < x) {
            s = mid + 1;
        } else {
            e = mid;
        }
    }

    return e;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; ++i) {
        scanf("%d", arr + i);
    }
    lis_len = START;
    lis_cur = START;
    LIS[START] = (ND){arr[START], START};
    pre[START] = END;

    for (int i = 1; i < n; ++i) {
        int x = arr[i];

        if (x > LIS[lis_len].v) {
            pre[i] = LIS[lis_len].idx;
            LIS[++lis_len] = (ND){x, i};
            lis_cur = i;
        } else {
            int t = lower_bound(x);
            if (t > 0) {
                pre[i] = LIS[t - 1].idx;
            } else {
                pre[i] = END;
            }
            LIS[t] = (ND){x, i};
        }
    }

    printf("%d\n", lis_len + 1);
    for (int i = 0; lis_cur > END; ++i) {
        lis[i] = arr[lis_cur];
        lis_cur = pre[lis_cur];
    }

    for (int i = lis_len; i >= 0; --i) {
        printf("%d ", lis[i]);
    }
    return 0;
}
This post is licensed under CC BY 4.0 by the author.