https://www.acmicpc.net/problem/2559
많은 깨달음을 주는 문제였다.
수열이 주어졌을 때, K(연속되는 수)의 합 중 가장 큰 값을 리턴해달라는 문제다.
N(수열의 개수) : 1 ~ 10만
K는 1과 N 사이의 정수이므로 최대는 10만 정도
단순하게 생각하면 10^10만이라 시간 안에 문제를 해결할 수 없다.
어떤 연속된 수의 합을 빠르게 구할 수 있는 방법은 누적합(prefix sum)을 이용하는 것이다.
누적합은 0 ~ k 구간의 합을 미리 차곡차곡 더해서 저장해 둔다.
문제의 예시를 보면
10 5
3 -2 -4 -9 0 3 7 13 8 -3
5개의 연속된 수열의 최댓값은 31이다.
각각의 누적합을 구해보면
1까지의 누적합은 0 + 3
2까지의 누적합은 0 + 3 - 2
3까지의 누적합은 0 + 3 -2 - 4
가만히 보면 3까지의 누적합은 2까지의 누적합 + 입력된 숫자다.
입력을 받을 때 누적합의 배열도 같이 채워나가면 된다.
-9 0 3 7 13의 구간 합을 알고 싶다면?
[13까지의 누적합] - [-4까지의 누적합]이다.
[13까지의 누적합] = 3 -2 -4 -9 0 3 7 13
[-4까지의 누적합] = 3 -2 -4
[구하려고 하는 것] = -9 0 3 7 13
누적합을 미리 정해놓고 가져다 쓰는 건 랜덤 접근이므로 O(1)
K는 최대 10만
10만 x O(1) => 시간 안에 해결이 가능하다.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int n, k, num, sum, ans = -10000004;
int arr[100005];
int main()
{
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
cin >> num;
arr[i] = arr[i - 1] + num;
}
for (int i = k; i <= n; i++)
{
ans = max(ans, arr[i] - arr[i - k]);
}
cout << ans << '\n';
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준 1620] 나는야 포켓몬 마스터 이다솜 (0) | 2024.08.16 |
---|---|
[백준 9375] 패션왕 신해빈 (0) | 2024.08.16 |
[백준 9996] 한국이 그리울 땐 서버에 접속하지 (0) | 2024.08.16 |
[백준 11655] ROT 13 (0) | 2024.08.15 |
[백준 11051] 이항 계수 2 (0) | 2022.01.11 |