CS 기초/알고리즘
[백준] 골드 5, 꿀 따기
잡템
2024. 2. 23. 01:56
문제
https://www.acmicpc.net/problem/21758
21758번: 꿀 따기
첫 번째 줄에 가능한 최대의 꿀의 양을 출력한다.
www.acmicpc.net
알고리즘 분류
그리디
누적 합
문제가 벌꿀과 벌의 배치 조건이 3가지로 분류가 가능하다
1. 벌 벌 꿀통
2. 꿀통 벌 벌
3. 벌 꿀통 벌
살펴보면 3가지 조건 모두 양쪽 끝은 고정되고 벌 또는 벌통이 양끝을 제외한곳에서 변경이 이루어짐을 알 수 있었다.
내경우엔 단순히 반복문과 벡터요소 합으로 계산하여 구현을 시도했다.
아래와같은 코드로 시도했으나 100점이아닌 55점에서 그치고 말았고 이런저런 시도를 해봤지만 여기서 더 개선은 되지않았다.
for (int i = 1; i < N - 1;++i)
{
//벌 벌 꿀통
int value1 = accumulate(vec.begin() + 1, vec.end(), 0) - vec[i] + accumulate(vec.begin() + i + 1, vec.end(), 0);
//꿀통 벌 벌
int value2 = accumulate(vec.begin(), vec.end() - 1, 0) - vec[N - 1 - i] + accumulate(vec.begin(), vec.end() - 1 - i, 0);
//벌 꿀통 벌
int value3 = accumulate(vec.begin() + 1, vec.begin() + 1 + i, 0) + accumulate(vec.begin() + i, vec.end() - 1, 0);
result = max(result,max(max(value1, value2),value3));
}
정답은 다른분의 코드를 참고하여 이해하게 되었다.
100점짜리 코드는 아래와 같다.
int main()
{
int N;
cin >> N;
vector<int> honey(N + 1, 0);
vector<int> sum(N + 1, 0);
for (int i = 1; i <= N;++i)
{
cin >> honey[i];
sum[i] = sum[i - 1] + honey[i];
}
int result = 0;
for (int i = 2; i < N; ++i)
{
//벌 벌 꿀통
int value1 = (sum[N] - sum[1] - honey[i]) + (sum[N] - sum[i]);
//꿀통 벌 벌
int value2 = (sum[N - 1] - honey[i]) + sum[i - 1];
//벌 꿀통 벌
int value3 = (sum[i] - honey[1]) + (sum[N - 1] - sum[i - 1]);
result = max(result, max(max(value1, value2), value3));
}
cout << result << "\n";
}
알고리즘이 누적합으로 분류되었던이유가 이것이였다.
sum에 배열 첫인덱스부터 의 누적합을 저장한뒤 이를 활용하는 방법으로 내가 vector의 accumulate를 사용했을때보다 코드도 훨씬 간결하게 정리가되었다. 덕분에 누적합관련 문제를 풀때 어떤방법을 사용해야될지 참고 할 수 있었다.