문제 링크: https://www.acmicpc.net/problem/10211
유명한 문제죠. 최대 부분 배열 문제(Maximum subarray problem)인데요, 여러 풀이가 있습니다.
분할정복으로 푸는 방법은 저번 게시물에 올렸으니 이번에는 dp로 풀어보겠습니다.
dp[i] = 'i번째 원소로 끝나는 부분배열 합의 최대값'이라고 해봅시다.
dp[i]는 최대값을 반환하니까 dp[i-1]도 최대값을 반환할겁니다. 따라서 dp[i] = dp[i-1] + arr[i] 라고 하면 말이 되는 것 같습니다.
이때, dp[i-1]이 음수인 경우, 해당 구간은 포함하지 않고 arr[i]만 포함하는 것이 최선이 됩니다. 부분 배열이 되려면 최소한 원소 한 개 이상을 포함해야 하니 부분 배열 합의 값이 음수값이 될 수 있죠. 따라서 아래 식처럼 쓸 수 있습니다.
\[dp[i] = max(0, dp[i-1]) + arr[i]\]
배열을 만들 필요는 없고, 변수 하나에 계속 누적해서 누적합(prefix sum)을 만들어주고 최대값 변수 하나 만들어서 max값을 찾으면 됩니다.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
vector<int> v(n);
for (auto& c : v)
cin >> c;
int max_val = -1e9;
int psum = 0;
for (int i = 0; i < n; ++i) {
psum = max(0, psum) + v[i];
max_val = max(max_val, psum);
}
cout << max_val << '\n';
}
return 0;
}
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][C++] 3425: 고스택 (0) | 2020.07.07 |
---|---|
[백준][C++] 9177: 단어 섞기 (0) | 2020.07.07 |
[백준][C++] 10219: Meats On The Grill (0) | 2020.07.07 |
[백준][C++] 17281: ⚾ (0) | 2020.07.07 |
[백준][C++] 7785: 회사에 있는 사람 (0) | 2020.07.06 |