BOJ 2156 포도주 시식
2156번: 포도주 시식
효주는 포도주 시식회에 갔다. 그 곳에 갔더니, 테이블 위에 다양한 포도주가 들어있는 포도주 잔이 일렬로 놓여 있었다. 효주는 포도주 시식을 하려고 하는데, 여기에는 다음과 같은 두 가지 규칙이 있다. 포도주 잔을 선택하면 그 잔에 들어있는 포도주는 모두 마셔야 하고, 마신 후에는 원래 위치에 다시 놓아야 한다. 연속으로 놓여 있는 3잔을 모두 마실 수는 없다. 효주는 될 수 있는 대로 많은 양의 포도주를 맛보기 위해서 어떤 포도주 잔을 선택해야 할지 고
www.acmicpc.net
해당 문제에서 유심히 봐야할 조건은
1. 연속으로 3잔을 마실 수 없다.
2. 안마시고 건너뛰어도 된다.
따라서 우리는 현재 n번째 와인을 마실 수 있을 때 세가지의 경우를 고려해볼 수 있다.
첫번째 - 이번 와인을 마시지 않은 경우
두번째 - 이번 와인을 마신 경우 but 이전 와인을 마시지 않은 경우
세번째 - 이번 와인을 마신 경우 and 이전 와인도 마신 경우
여기서 dp 배열은 i번째 와인을 마실 수 있을 때, 위의 3개의 경우로 나누어서 각각의 i번째 와인마다 최적해를 저장한 테이블이고 wine 배열은 입력받은 wine 정보를 저장한다.
첫번째 : dp[i][0] = max(dp[i-1][0], dp[i-1][1], dp[i-1][1] )
두번째 : dp[i][1] = dp[i-1][0] + wine[i] (dp[i-1][0] 이 이전에 와인을 마시지 않은 경우이므로)
세번째 : dp[i][2] = dp[i-1][1] + wine[i] (dp[i-1][1] 이 이전에 와인을 마신 경우이므로)
이를 그대로 구현하면 된다.
import java.util.*;
import java.io.*;
public class Main {
private static int max(int n, int m) {
if(n>m) return n;
else return m;
}
private static int []wine;
private static int [][] dp;
public static void main(String[] args)throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk= new StringTokenizer(br.readLine());
int n = Integer.parseInt(stk.nextToken());
wine = new int[n+1];
dp = new int[n+1][3];
for(int i=1; i<n+1;i++) {
stk = new StringTokenizer(br.readLine());
int input= Integer.parseInt(stk.nextToken());
wine[i]= input;
}
dp[1][0]=0;
dp[1][1]=wine[1];
dp[1][2]=wine[1];
if(n>=2) { //n == 1 일때는 이걸 수행하면 런타임 에러가 난다.
dp[2][0]=wine[1];
dp[2][1]=wine[2];
dp[2][2]=dp[1][1]+wine[2];
}
for(int i=3; i<=n ; i++) {
dp[i][0]=max(dp[i-1][0],max(dp[i-1][1], dp[i-1][2])); //안마신다
dp[i][1]=dp[i-1][0]+wine[i]; // 직전에 안마심 + 지금 마심
dp[i][2]=dp[i-1][1]+wine[i]; // 직전에 마심 + 지금 마심
}
int ans = max(dp[n][0],max(dp[n][1],dp[n][2]));
System.out.println(ans);
}
}