728x90
반응형
문제
효주는 포도주 시식회에 갔다. 그 곳에 갔더니, 테이블 위에 다양한 포도주가 들어있는 포도주 잔이 일렬로 놓여 있었다.
효주는 포도주 시식을 하려고 하는데, 여기에는 다음과 같은 두 가지 규칙이 있다.
포도주 잔을 선택하면 그 잔에 들어있는 포도주는 모두 마셔야 하고, 마신 후에는 원래 위치에 다시 놓아야 한다.
연속으로 놓여 있는 3잔을 모두 마실 수는 없다.
효주는 될 수 있는 대로 많은 양의 포도주를 맛보기 위해서 어떤 포도주 잔을 선택해야 할지 고민하고 있다.
1부터 n까지의 번호가 붙어 있는 n개의 포도주 잔이 순서대로 테이블 위에 놓여 있고,
각 포도주 잔에 들어있는 포도주의 양이 주어졌을 때, 효주를 도와 가장 많은 양의 포도주를 마실 수 있도록 하는 프로그램을 작성하시오.
예를 들어 6개의 포도주 잔이 있고, 각각의 잔에 순서대로 6, 10, 13, 9, 8, 1 만큼의 포도주가 들어 있을 때,
첫 번째, 두 번째, 네 번째, 다섯 번째 포도주 잔을 선택하면 총 포도주 양이 33으로 최대로 마실 수 있다.
접근법
현재 잔을 기준으로 (N번째 까지 왔다 가정)
계산할 수 있는 경우의 수는 아래와 같다
1. 현재잔을 마시는 경우(이번이 두번째 잔인 경우)
2. 현재잔을 마시는 경우(이번이 첫번째 잔인 경우)
3. 현재잔을 마시지 않는경우(이전에 이미 두잔을 마신경우)
이를 점화식으로 표현하면 아래와 같다.
dp[i] = std::max(dp[i - 3] + nums[i - 1] + nums[i], dp[i - 2] + nums[i]);
dp[i] = std::max(dp[i], dp[i - 1]);
dp에는 이전의 최댓값을 저장하며 나아간다.
out of bounds 가 나지 않게 dp[3]까지만 경우의 수를 미리 측정해 넣어주면 코드는 아래와 같다.
코드
#include <iostream>
#include <vector>
using namespace std;
int main()
{
int N;
cin >> N;
vector<int> nums(N + 1, 0);
vector<int> dp(N + 1, 0);
for (int i = 0; i < N; i++)
{
int num;
cin >> num;
nums[i] = num;
}
//dp[3] = dp[0] + nums[2] + nums[3] or dp[1] + nums[3] or dp[2]
dp[0] = nums[0];
dp[1] = nums[0] + nums[1];
dp[2] = std::max(nums[0] + nums[1], nums[1] + nums[2]);
dp[2] = std::max(dp[2], nums[0] + nums[2]);
for (int i = 3; i < N; i++)
{
dp[i] = std::max(dp[i - 3] + nums[i - 1] + nums[i], dp[i - 2] + nums[i]);
dp[i] = std::max(dp[i], dp[i - 1]);
}
cout << dp[N - 1];
}
반응형
'알고리즘' 카테고리의 다른 글
백준 2606번 - 바이러스 (C++/BFS/Graph) (1) | 2024.03.25 |
---|---|
백준 4963번 - 섬의 개수(C++/그래프/너비 우선 탐색/BFS) (0) | 2024.03.13 |
백준 10816번 - 숫자카드2(C++/병합 정렬/ Merge Sort/ 이분 탐색) (0) | 2024.03.07 |
백준 1992번 - 쿼드트리(C++/분할 정복/ 재귀 함수) (0) | 2024.03.04 |
백준 2667 번 - 단지번호붙이기(C++/BFS/Graph) (0) | 2024.02.29 |