ps
[백준] 2208 - 보석 줍기
kariskan
2023. 6. 27. 18:30
https://www.acmicpc.net/problem/2208
2208번: 보석 줍기
화영이는 고대 유적을 탐사하던 도중 보석을 발견했다. 유적 속에는 N(1 ≤ N ≤ 100,000)개의 보석들이 일렬로 놓여 있었다. 각각의 보석의 가치는 다를 수 있기 때문에, 화영이는 가급적 많은 이득
www.acmicpc.net
문제를 해석해 보면,
N개의 요소를 가지는 배열중 m개 이상의 연속된 부분 집합 중 최대 합
을 구하는 문제이다.
일반적인 부분 합 문제로 풀려면 O(N^2)의 시간 복잡도가 소요돼 실패한다.
따라서 dp를 이용해 풀 것이다.
dp[i] = i번째 요소의 부분집합 중 m개 이상의 연속된 집합의 최대 합
으로 정의하자.
그렇다면 dp 배열은 다음과 같은 두 가지 상황이 있다.
- 현재 i번째 인덱스의 요소를 추가하는 경우( dp[i - 1] + a[i] )
- 현재 인덱스에서 앞으로 m개의 인덱스의 합을 세는 경우( sum[i] - sum[i - m] )
따라서 완성된 점화식은 다음과 같다.
dp[i] = max(dp[i - 1] + a[i], sum[i] - sum[i - m])
문제를 풀 때에는 변수 하나로 배열 하나를 줄였다.
#include <iostream>
using namespace std;
int a[100001], dp[100001], n, m;
int main() {
cin >> n >> m;
int ans = 0, mindp = 0;
for (int i = 1; i <= n; i++) {
cin >> a[i];
dp[i] = dp[i - 1] + a[i];
if (i >= m) {
mindp = min(mindp, dp[i - m]);
ans = max(ans, dp[i] - mindp);
}
}
cout << ans;
}