반응형

문제 링크

 

11055번: 가장 큰 증가 부분 수열

수열 A가 주어졌을 때, 그 수열의 증가 부분 수열 중에서 합이 가장 큰 것을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 인 경우에 합이 가장 큰 증가 부분 수열은 A = {1, 100, 2, 50, 60, 3, 5, 6, 7, 8} 이고, 합은 113이다.

www.acmicpc.net

 

풀이 ) DP

  LIS라고 부르는 문제이다.

  앞에서 부터 시작하여 숫자를 하나씩 추가해 나가면서 부분 문자열의 합의 최대를 찾는 문제이다.

  예제 입력을 예로하면 i는 4일 때 memo[4] = arr[4] = 60이다.

  1 100 2 50의 부분 수열을 순회하면서

  •   j = 0일 때 1 < 60 이고 61 > 60 이므로 memo[4] = 61 이 된다.
  •   j = 1일 때 100 > 60 이므로 다음으로 넘어간다
  •   j = 2일 때 2 < 60 이고 63 > 61 이므로 memo[4] = 63 가 된다. ( ∵ memo[2] = 3)
  •   j = 3일 때 50 < 60 이고 113 > 63 이므로 memo[4] = 113 가 된다. ( ∵ memo[3] = 53)

  위와 같은 방식으로 수열의 끝까지 간 후 memo[0] 부터 memo[n-1] 중 최댓값을 출력한다.

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

int arr[1002], memo[1002];

int main(void)
{
    int n, ans = 0;
    scanf("%d", &n);
    for(int i = 0; i < n; ++i)
        scanf("%d", arr+i);

    for(int i = 0; i < n; ++i){
        memo[i] = arr[i];
        for(int j = 0; j < i; ++j){
            if(arr[j] < arr[i])
                memo[i] = max(memo[i], memo[j]+arr[i]);
        }
        ans = max(ans, memo[i]);
    }
    printf("%d\n", ans);
    return 0;
}

 

주의점 )

  - 반복문 시작 시 매번 memo[i]가 최소 자신을 포함하므로 memo[i] = arr[i]로 값을 넣고 시작한다.

반응형

'문제풀이 > 백준' 카테고리의 다른 글

[C++] 백준 - 2164 : 카드2  (0) 2020.03.20
[C++] 백준 - 10845 : 큐  (0) 2020.03.20
[C++] 백준 - 16500 : 문자열 판별  (0) 2020.03.18
[C++] 백준 - 12865 : 평범한 배낭  (0) 2020.03.18
[C++] 백준 - 11051 : 이항 계수 2  (0) 2020.03.18

+ Recent posts