본문 바로가기
백준BOJ/동적 계획법

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

by 이일아 2022. 6. 11.
반응형

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

 

11053번: 가장 긴 증가하는 부분 수열

수열 A가 주어졌을 때, 가장 긴 증가하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 20, 10, 30, 20, 50} 인 경우에 가장 긴 증가하는 부분 수열은 A = {10, 20, 10, 30, 20, 50} 이

www.acmicpc.net

 

 

 

EXPLANATION

N번째 숫자들 중에서 임의로 선택해서 가장 긴 증가하는 부분 수열을 만들어야 한다.

 

N번째 숫자들 중에서 임의로 선택해서 증가하는 모든 부분 수열을 구하는 경우는 

1<= i <=N 일 때, 각 i번째까지의 숫자들 중에서 i번째 숫자가 가장 큰 증가하는 부분 수열을 구하는 각 각의 경우들을 다 모은 합집합에 포함되어 있다.

 

ex)

?: 선택 유무 모름     O: 선택     X: 비선택

따라서, 위의 각 각의 경우의 가장 긴 수열을 만드는 경우를 구한 후, 거기서 가장 긴 수열을 가지는 것이 답이다.

 

 

i번째 숫자를 arr[i]라고 하고

i번째까지의 숫자들 중에서 i번째 숫자가 가장 크면서 가장 긴 증가하는 부분 수열의 길이를 dp[i]라고 하자.

 

일단 i번째 이전에 수가 없거나 모든 수가 arr[i]보다 큰 경우에  dp[i]  수열이 arr[i]만 가지므로 dp[i] = 1이 된다.

그게 아니라면, 이후 1 <=  j < i 범위를 오름차순으로 돌면서 arr[i]가 arr[j]보다 큰 경우에, dp[j]의 수열에 arr[i]를 추가해서

dp[i]를 dp[j] + 1로 갱신하면 된다.

그러면 1<= j < i일 때 arr[i]가 arr[j]보다 큰 경우의 dp[j] + 1들 모두 비교해서 가장 큰 값이 dp[i]가 된다.

 

 

1<= i <=N에서 dp[i]를 모두 비교해서 가장 큰 값이 N번째 숫자들 중에서 임의로 선택해서 가장 긴 증가하는 부분 수열을 만드는 경우이다.

 

 

ex)

6
10 20 10 30 20 50

 

i = 1, dp[1] 구하기:

dp[1]은 i 자신만 포함가능하므로 1

maxDP = dp[1]

 

 

i = 2,dp[2] 구하기:

arr[2] > arr[1]

max(1, dp[1])

dp[2] = dp[1] + 1 = 2

maxDP = max(dp[1], dp[2]) = dp[2]

 

i = 3,dp[3] 구하기:

arr[3] <= arr[1], arr[2] 

따라서 dp[3]은 i 자신만 포함가능하므로 1

maxDP = max(dp[2], dp[3]) = dp[2]

 

 

i = 4,dp[4] 구하기:

arr[4] > arr[1], arr[2], arr[3]

max(dp[1], dp[2], dp[3]) = dp[2]

dp[4] = dp[2] + 1 = 3

maxDP = max(dp[2], dp[4]) = dp[4]

 

i = 5,dp[5] 구하기:

arr[5] > arr[1], arr[3]

arr[5] <= arr[2], arr[4] 

max(1, dp[1], dp[3]) = 1

dp[4] = 1 + 1 = 2

maxDP = max(dp[4], dp[5]) = dp[4]

 

 

 

i = 6,dp[6] 구하기:

arr[6] > arr[1], arr[2], arr[3], arr[4], arr[5]

max(1, dp[1], dp[2], dp[3], dp[4], dp[5]) = dp[4]

dp[4] = dp[4] + 1 = 4

maxDP = max(dp[4], dp[6]) = dp[6]

 

따라서 답은 dp[6] = 4

 

 

 

 

위 설명만 부분 코드로 나타내면

int maxDP = 0;

for (int i = 1; i <= N; i++)
    {
        
        
        dp[i] = 1;
        for (int j = 1; j < i; j++)
        {
            if (arr[i] > arr[j])	
            {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        
        
        maxDP = max(maxDP, dp[i]);
    }

 

 

 

 

.

 

 

CODE

#include <iostream>

using namespace std;

int main()
{

    int N;
    int dp[1001] = {};    //for [1, N]
    int arr[1001] = {};
    int maxDP = 0;

    cin >> N;

    for (int i = 1; i <= N; i++)
    {
        cin >> arr[i];
    }

    for (int i = 1; i <= N; i++)
    {
        dp[i] = 1;

        for (int j = 1; j < i; j++)
        {
            if (arr[i] > arr[j]) 
            {
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
        maxDP = max(maxDP, dp[i]);
    }

    cout << maxDP << "\n";
}

 

 

반응형

'백준BOJ > 동적 계획법' 카테고리의 다른 글

백준 9251 LCS  (0) 2022.06.12
백준 11054 가장 긴 바이토닉 부분 수열  (0) 2022.06.12
백준 2156 포도주 시식  (0) 2022.06.11
백준 10844 쉬운 계단 수  (0) 2022.06.10
백준 1463 1로 만들기  (0) 2022.06.10

댓글