길민호(ethan.mino)
코딩수첩
길민호(ethan.mino)
전체 방문자
오늘
어제
  • 분류 전체보기 (215)
    • Computer Science (0)
    • Web (6)
      • CSS (0)
      • HTML (0)
    • Node.js (0)
    • Javascript (2)
    • Java (46)
      • Spring (27)
      • Jsp (0)
    • C\C++ (2)
    • Programming (0)
    • AI (0)
    • Database (7)
    • Git (5)
    • Algorithm (119)
      • Stack (0)
      • Queue (0)
      • Linked List (0)
      • Sort (0)
      • Simulation (27)
      • Recursion (0)
      • Backtracking (4)
      • Two Pointer (3)
      • Dynamic Programming (19)
      • Greedy (10)
      • Graph (3)
      • Dijkstra (1)
      • BFS\DFS (8)
      • Floyd (1)
      • MST (4)
      • Tree (4)
      • Binary Search (8)
      • Binary Search Tree (4)
    • IntelliJ (4)
    • Vscode (0)
    • Operating System (0)
    • 후기 (3)
    • 성장일지 (13)
    • 스터디 (7)
    • 설치 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅡ

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
길민호(ethan.mino)

코딩수첩

Algorithm/Dynamic Programming

[백준 11055번] 가장 큰 증가 부분 수열 (C++)

2022. 4. 15. 03:51

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

 

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

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

www.acmicpc.net


가장 큰 증가 부분 수열은 n이 최대 1,000이므로 백트래킹을 이용하는 경우 시간초과가 발생할 수 있습니다. 이 문제는 다이나믹 프로그래밍을 이용하여 해결할 수 있습니다. 

 

부분 수열의 첫 원소는 어느 숫자든 가능하며, 이후의 원소는 이전 원소보다 커야합니다.

따라서 시작 원소 이후, 첫 원소보다 큰 원소들에 대해 가장 큰 증가 부분 수열의 합을 계산하고, 그 중에서도 가장 큰 합과 시작 원소를 더해주면 가장 큰 증가 부분 수열의 합을 계산할 수 있습니다.

또한 앞서 언급한 것처럼, 어느 원소든 시작점이 될 수 있기 때문에 위와 같은 연산을 모든 원소에 대해 수행해주면 됩니다.

 

아래는 전체 코드입니다.

#include <bits/stdc++.h>
using namespace std;

int arr[1001], d[1001];
int n;

int sum(int idx){   // idx부터 시작하여 가장 큰 증가 부분 수열의 합을 반환하는 함수
    if(d[idx] != 0)
        return d[idx];
    else{
        int ans = INT_MIN;    // idx번째 원소를 제외한 나머지 가장 큰 수열의 합
        bool biggest = true;    // idx 이후로 arr[idx]보다 큰 원소가 있는지를 나타내는 flag
        for(int i = n - 1; i > idx; i--){
            if(arr[idx] < arr[i]){
                biggest = false;    // idx 이후로 arr[idx]보다 큰 원소가 있음
                ans = max(ans, sum(i)); // arr[idx]보다 큰 원소를 시작점으로 가장 큰 증가 부분 수열의 합을 계산
            }
        }

        if(biggest) d[idx] = arr[idx]; // idx 이후로 arr[idx]보다 큰 것이 하나도 없다면, idx부터 시작하여 가장 큰 증가 부분 수열의 합은 자기 자신 뿐
        else d[idx] = arr[idx] + ans; // 그렇지 않다면 가장 큰 
        return d[idx];
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;

    for(int i = 0; i < n; i++) cin >> arr[i];   // 수열 입력 받음
    for(int i = 0; i < n; i++) sum(i);  // 수열의 각 원소를 시작점으로 잡고, 가장 큰 증가 부분 수열의 합을 구함

    cout << *max_element(d, d + 1001);  // 시작점에 따른 가장 큰 증가 부분의 수열 중 가장 큰 합을 출력
}

 

아래는 문제 풀이에 사용된 테스트 케이스입니다.

4
3 1 2 3
-> 6

7
2 1 100 97 98 99 101
-> 397

'Algorithm > Dynamic Programming' 카테고리의 다른 글

[백준 15486번] 퇴사 2 (C++)  (0) 2022.05.05
[백준 10844번] 쉬운 계단 수 (C++)  (0) 2022.05.04
[백준 1912번] 연속합 (C++)  (0) 2022.04.15
[백준 2193번] 이친수 (C++)  (0) 2022.04.14
[백준 12852번] 1로 만들기 2 (C++)  (0) 2022.04.14
    'Algorithm/Dynamic Programming' 카테고리의 다른 글
    • [백준 15486번] 퇴사 2 (C++)
    • [백준 10844번] 쉬운 계단 수 (C++)
    • [백준 1912번] 연속합 (C++)
    • [백준 2193번] 이친수 (C++)
    길민호(ethan.mino)
    길민호(ethan.mino)
    💻 호기심 많은 서버 개발자 길민호입니다.

    티스토리툴바