문제 링크 : https://www.acmicpc.net/problem/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이다. 입력첫째 줄에 수열 A의 크기 N (1 ≤ N ≤ 1,000)이 주어진다. 둘째 줄에는 수열 A를 이루고 있는 Ai가 주어진다. (1 ≤ Ai ≤ 1,000) 출력첫째 줄에 수열 A의 합이 가장 큰 증가 부분 수열의 합을 출력한다. 예제 입력 110 1 100 2 50 60 3 5 6 7 8 예제 출력 1113 |
[ 문제 풀이 ]
D[i] = A[i]가 마지막으로 오는 증가 부분 수열 중 가장 큰 합
D[1] = A[1]
D[2] = max(A[2], D[1] + A[2] if A[1] < A[2])
D[3] = max(A[3], D[1] + A[3] if A[1] < A[3], D[2] + A[3] if A[2] < A[3])
...
D[i] = max(D[j] + A[i], if j < i and A[j] < A[i])
ex) D[4] 구하기
D[j]는 A[j]를 반드시 사용하여(A[j]가 마지막으로 오게된다) 만드는 증가 부분 수열 중 가장 큰 합을 저장하고 있다.
[ 최종 구현(C++) ]
#include <stdio.h>
#define MAX_NUMBER 1002
#define MAX(a,b) ((a) > (b) ? (a) : (b))
int A[MAX_NUMBER] = { 0, };
int D[MAX_NUMBER] = { 0, };
int main(void)
{
int N;
int result = 0;
scanf("%d", &N);
for (register int i = 1; i <= N; i++)
scanf("%d", &A[i]);
D[1] = A[1];
for (register int i = 2; i <= N; i++)
{
D[i] = A[i];
for (register int j = 1; j <= i - 1; j++)
{
if (A[j] < A[i])
D[i] = MAX(D[i], D[j] + A[i]);
}
}
for (register int i = 1; i <= N; i++)
{
result = MAX(result, D[i]);
}
printf("%d\n", result);
return 0;
}'Algorithm > 문제풀이' 카테고리의 다른 글
| [다이나믹 프로그래밍] 가장 긴 바이토닉 부분 수열 (0) | 2018.08.11 |
|---|---|
| [다이나믹 프로그래밍] 가장 긴 감소하는 부분 수열 (0) | 2018.08.11 |
| [다이나믹 프로그래밍] 가장 긴 증가하는 부분 수열 (0) | 2018.08.10 |
| [다이나믹 프로그래밍] 포도주 시식 (0) | 2018.08.10 |
| [다이나믹 프로그래밍] 스티커 (0) | 2018.08.07 |