#문제
효주는 포도주 시식회에 갔다. 그 곳에 갔더니, 테이블 위에 다양한 포도주가 들어있는 포도주 잔이 일렬로 놓여 있었다. 효주는 포도주 시식을 하려고 하는데, 여기에는 다음과 같은 두 가지 규칙이 있다.
-
포도주 잔을 선택하면 그 잔에 들어있는 포도주는 모두 마셔야 하고, 마신 후에는 원래 위치에 다시 놓아야 한다.
-
연속으로 놓여 있는 3잔을 모두 마실 수는 없다.
효주는 될 수 있는 대로 많은 양의 포도주를 맛보기 위해서 어떤 포도주 잔을 선택해야 할지 고민하고 있다. 1부터 n까지의 번호가 붙어 있는 n개의 포도주 잔이 순서대로 테이블 위에 놓여 있고, 각 포도주 잔에 들어있는 포도주의 양이 주어졌을 때, 효주를 도와 가장 많은 양의 포도주를 마실 수 있도록 하는 프로그램을 작성하시오.
예를 들어 6개의 포도주 잔이 있고, 각각의 잔에 순서대로 6, 10, 13, 9, 8, 1 만큼의 포도주가 들어 있을 때, 첫 번째, 두 번째, 네 번째, 다섯 번째 포도주 잔을 선택하면 총 포도주 양이 33으로 최대로 마실 수 있다.
입력
첫째 줄에 포도주 잔의 개수 n이 주어진다. (1≤n≤10,000) 둘째 줄부터 n+1번째 줄까지 포도주 잔에 들어있는 포도주의 양이 순서대로 주어진다. 포도주의 양은 1,000 이하의 음이 아닌 정수이다.
출력
첫째 줄에 최대로 마실 수 있는 포도주의 양을 출력한다.
#작성 코드
#include <iostream>
#include <cmath>
using namespace std;
int n;
int wine[10001]; // 각 포도주잔에 들어있는 포도주의 양 저장
int wineSum[10001]={0,}; // i번째 포도주잔까지 마실때 최대로 마실수있는 포도주의 양
void input(){
cin>>n;
for(int i=1; i<=n; i++){
cin>>wine[i];
}
}
int choose(){
wineSum[0]=0;
wineSum[1] = wine[1];
wineSum[2] = wine[1]+wine[2];
for(int i=3; i<=n; i++){
// oox 경우와 oxo경우, xoo경우 중 최대
wineSum[i] = max( wineSum[i-1], wineSum[i-2]+wine[i] );
wineSum[i] = max( wineSum[i], wineSum[i-3]+wine[i-1]+wine[i]);
}
return wineSum[n];
}
int main(){
input();
cout<<choose();
return 0;
}
##
wineSum[i]는 i번째 포도주 잔까지 마실 때 최대로 마실 수 있는 포도주의 양을 저장한다.
2579번, 계단 오르기 문제와 다른 점은 "무조건 마지막 포도주를 마셔야 하는 것이 아니다"라는 것이다.
#191217 review
복습 중에 기존의 1차원 dp풀이말고, 2차원 dp로 푸는 아이디어가 생각나서 다시 풀어보았다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
int wine_solve(int n){
for(int i=1; i<=n; i++){
// 어느 케이스 다음에라도 선택하지 않는 선택을 할 수 있다.
wine_d[i][0] = max(wine_d[i-1][0], max(wine_d[i-1][1], wine_d[i-1][2]));
// 연속으로 마신 포도주가 1잔이 되려면 연속 0인 상태에서 한 잔 마시면 된다.
wine_d[i][1] = wine_d[i-1][0] + wine[i];
// 연속으로 1잔 마신 상태에서 한 잔 더 마시면 연속으로 두 잔 마신 상태가 된다.
wine_d[i][2] = wine_d[i-1][1] + wine[i];
}
// 마신 포도주 양이 가장 많은 케이스를 찾아서 출력한다.
int maxsum=0;
for(int i=1; i<=n; i++){
maxsum = max(maxsum, wine_d[i][0]);
maxsum = max(maxsum, wine_d[i][1]);
maxsum = max(maxsum, wine_d[i][2]);
}
return maxsum;
}
|
cs |
wine_d[i][0] : i번째에 연속된 마신 포도주 잔 0개.
wine_d[i][1] : i번째에 연속된 마신 포도주 잔 1개.
wine_d[i][2] : i번째에 연속된 마신 포도주 잔 2개.
'BOJ' 카테고리의 다른 글
BOJ 1012번 :: 유기농 배추 (0) | 2019.12.05 |
---|---|
BOJ 11053번 :: 가장 긴 증가하는 부분수열 (0) | 2019.12.05 |
BOJ 2667번 :: 단지번호붙이기 (0) | 2019.12.04 |
BOJ 10844번 :: 쉬운 계단수 (0) | 2019.12.03 |
BOJ 2606번 :: 바이러스 (0) | 2019.12.02 |