PS/BOJ

BOJ 11053 가장 긴 증가하는 부분 수열

모달조아 2021. 7. 4. 23:05

boj 11053 가장 긴 증가하는 부분 수열

D[i]가 어떻게 작동해야 문제에서 원하는 답을 잘 찾아낼 수 있을까를 생각해봤다.

위 그림과 같이 작동해야하는데, 그래서 D[i]를 i번째 원소를 마지막으로 하는 가장 긴 부분 수열의 길이라고 정의하였다. a[i]는 수열을 담는 배열이다. D[i]는 길이이기에 1씩 점점 증가하는 방식으로 식을 정의해줘야하는데, 언제 1씩 증가시켜야하는지 조건을 정해주는 것이 이 문제의 핵심이다. 먼저 코드를 보고 코드에 대해 설명해보겠다.

#include <iostream>
#include <algorithm>
using namespace std;

int n;
int mx;
int a[1005];
int D[1005];

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

    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

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

        for (int j = 1; j < i; j++)
        {
            if (a[j] < a[i] && D[j] >= D[i])
                D[i] = D[j] + 1;
        }
    }

    for (int i = 1; i <= n; i++)
        mx = max(mx, D[i]);

    cout << mx;
}

D[i]는 i번째 원소를 포함하는 가장 긴 부분 수열의 길이이므로 D[i]의 초기 값은 전부 1로 지정해준다. 앞서 말한 D[i]가 1씩 커질 수 있는 조건에 대해 설명해보자면,

  • a[i] > a[j] (단, i > j)
    : 점점 증가하는 수열이기에 위 조건을 만족해야한다.
  • D[j] >= D[i]
    : 이 조건을 만족하지 않으면, 어떻게 되는지 한 번 살펴보자.

    i가 4이고 j가 2인 경우를 지나 위 테이블과 같은 상황이 만들어졌다. D[i] >= D[i]라는 조건이 없다면, j가 3인 경우를 지날 때 아래와 같은 상황이 발생할 것이다.

    그렇기에 위 두 조건을 동시에 만족하는 경우에만 D[i] = D[j] + 1 을 실행한다.