티스토리 뷰
해당 문제에서 유심히 봐야할 조건은
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);
}
}
'algorithm > problem solving' 카테고리의 다른 글
BOJ 11054 가장 긴 바이토닉 부분 수열 (0) | 2020.04.17 |
---|---|
BOJ 2579 계단 오르기 (0) | 2020.04.15 |
BOJ 1931 회의실배정 (0) | 2020.04.14 |
BOJ 11657 타임머신 (0) | 2020.04.14 |
BOJ 2667 단지번호붙이기 (0) | 2020.04.08 |
댓글