
수열에
[1, -1, ...]또는[-1, 1, ...]패턴을 곱했을 때 나올 수 있는 연속 부분 수열의 합 중 최댓값을 구하는 문제다. 부분 수열의 합을 구하는 가장 빠른 방법인 카데인 알고리즘(Kadane's Algorithm)을 두 가지 펄스 패턴에 동시에 적용하여 으로 해결한다.
max) 찾기.long long 자료형이 필수다.[1, -1, 1, ...]과 [-1, 1, -1, ...] 두 가지 경우밖에 없다.sequence[i])에 두 가지 펄스 패턴을 각각 적용한다.sequence[i] * (-1)^isequence[i] * (-1)^(i+1)current_sum)을 더해나간다.total_max를 갱신한다.#include <vector>
#include <algorithm>
long long solution(std::vector<int> sequence) {
long long total_max = 0;
long long current_sum1 = 0; // 패턴 1용 누적합
long long current_sum2 = 0; // 패턴 2용 누적합
for (int i = 0; i < sequence.size(); ++i) {
long long val1, val2;
// 인덱스가 짝수일 때와 홀수일 때를 나누어 패턴 각각 적용
if (i % 2 == 0) {
val1 = (long long)sequence[i]; // 패턴 1: 1 곱하기
val2 = (long long)sequence[i] * -1; // 패턴 2: -1 곱하기
} else {
val1 = (long long)sequence[i] * -1; // 패턴 1: -1 곱하기
val2 = (long long)sequence[i]; // 패턴 2: 1 곱하기
}
// 카데인 알고리즘: 누적합이 0보다 작아지면 버리고 0부터 다시 시작
current_sum1 = current_sum1 + val1;
if (current_sum1 < 0) {
current_sum1 = 0;
}
current_sum2 = current_sum2 + val2;
if (current_sum2 < 0) {
current_sum2 = 0;
}
// 전체 최댓값 갱신
if (current_sum1 > total_max) {
total_max = current_sum1;
}
if (current_sum2 > total_max) {
total_max = current_sum2;
}
}
return total_max;
}
int 범위를 초과할 수 있다. 모든 누적 변수를 long long으로 선언하여 오버플로우를 방지했다.total_max를 0으로 초기화했을 때 모든 값이 음수라면 문제가 될 수 있다. 하지만 펄스 수열은 원소의 부호를 뒤집기 때문에, 적어도 하나의 원소는 양수(또는 0)가 되므로 0으로 초기화해도 정답을 구할 수 있다.| 항목 | 내용 |
|---|---|
| 유형 | 다이나믹 프로그래밍 (DP), 카데인 알고리즘 |
| 체감 난이도 | 중 (카데인 알고리즘을 모르면 어려움) |
| 복잡도 | 시간: , 공간: |
| 새로 배운 것 | 카데인 알고리즘의 핵심 아이디어("누적합이 음수면 버린다")를 활용하여 연속 부분 수열의 최댓값을 효율적으로 구하는 법을 익혔다. |