백준의 가장 큰 증가 부분수열(11055) 문제이다.
( 문제 바로가기 )
[ 문제풀이 ]
1) 주어진 수열에서 부분수열을 만들어야 하는데, 증가하는 부분 수열이여야 하고, 부분수열의 각 원소들의 합이 최대가
되는 부분 수열을 찾아야 한다.
문제를 풀기 전에 백준에 '가장 긴 증가하는 부분 수열(11053)' 이라는 문제가 있는데
이 문제에 대한 풀이를 먼저 읽고 오는 것을 권장한다.
왜냐하면 너무나도 비슷한 로직을 가지고 있고, 위의 문제에서 한 부분만 바꾸면 이 문제를 해결할 수 있기 때문에
이 글을 읽기 전에 위의 문제를 풀어보고 풀이까지 보고 오는 것을 권장한다.
( 권장드리는 것 뿐, 반드시 그렇게 해야 하는 것은 아닙니다 ! )
[ 백준 - 가장 긴 증가하는 부분 수열(11053) 문제 ]
[ 백준 - 가장 긴 증가하는 부분 수열(11053) 풀이 ]
2) 먼저 본인은 이 문제를 해결하기 위해서 2가지 배열을 사용했다.
먼저 입력으로 주어지는 수열을 저장하는 Arr[], 최댓값을 저장하는 배열 DP[] 이렇게 1차원 배열 2가지를 사용했다.
DP[a] = b 의 의미는 "a번 인덱스 까지의 가장 큰 부분 수열의 합은 b 입니다." 이다.
그렇다면 a번 인덱스에서의 가장 큰 부분 수열을 찾기 전에, 가장 작은 부분 수열의 값은 얼마일까 ??
바로 Arr[a]일 것이다. { 1, 2, 3, 4, 5 } 라는 수열이 있을 때, DP[2]의 값을 찾는다고 가정해보자.
가장 큰 부분 수열을 찾기 전에, 가장 작은 부분 수열은, '2' 이 원소 하나로만 이루어진 수열일 것이고 그 값은
Arr[2]인 2가 된다. 즉 DP[a] 의 초기값은 Arr[a]가 된다는 의미이다.
3) 그렇다면, 본격적으로 문제를 풀어보자. 일단 부분 수열을 찾는 가장 큰 조건은 증가하는 부분 수열이여야 한다는 것이다.
즉, 우리가 찾고자 하는 해당 인덱스에서의 증가하는 부분 수열을 구하려면, 1번부터 해당 인덱스 까지 증가하면서 비교를
해줘야 한다는 것이다. 이런식으로 !!
1 2 3 4 5 6 7 8 | for(int i = 1; i <= N; i++) { DP[i] = Arr[i] // 설명한 DP[i]의 초기값 for(int j = 1; j<= N; j++) { if(Arr[j] < Arr[i]) ~~ } } | cs |
또 하나의 조건이 더있다. 우리는 각 원소들의 합이 최대가 되는 수열을 찾아내어야 한다.
즉, DP[i] < DP[j] + Arr[i] 라는 조건이 더 붙어줘야 한다. 지금 까지의 최댓값 + Arr[i]를 더했을 때, 최대가 된다면
DP[i]의 최댓값은 DP[j] + Arr[i] 가 될 것이기 때문이다.
4) 이런식으로 DP[1] ~ DP[N]까지의 값을 모두 구해주고, 그 중에서 최댓값을 찾아내면 문제를 해결할 수 있을 것이다.
[ 소스코드 ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #include<iostream> #define endl "\n" #define MAX 1001 using namespace std; int N; int Arr[MAX]; int DP[MAX]; void Input() { cin >> N; for (int i = 1; i <= N; i++) { cin >> Arr[i]; } } void Solution() { int Max = 0; for (int i = 1; i <= N; i++) { DP[i] = Arr[i]; for (int j = 1; j < i; j++) { if (Arr[j] < Arr[i] && DP[i] < DP[j] + Arr[i]) { DP[i] = DP[j] + Arr[i]; } } if (Max < DP[i]) Max = DP[i]; } cout << Max << endl; } void Solve() { Input(); Solution(); } int main(void) { ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); //freopen("Input.txt", "r", stdin); Solve(); return 0; } | cs |
'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글
[ 백준 9663 ] N-Queen (C++) (0) | 2019.01.15 |
---|---|
[ 백준 2580 ] 스도쿠 (C++) (8) | 2019.01.14 |
[ 백준 2503 ] 숫자 야구 (C++) (4) | 2019.01.13 |
[ 백준 2980 ] 도로와 신호등 (C++) (0) | 2019.01.13 |
[ 백준 1987 ] 알파벳 (C++) (4) | 2019.01.13 |