일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- DP
- 자바
- 소숫점처리
- 백준
- Algorithm
- SQL
- n x 2 타일링 2
- 2156
- select
- 변수
- 입출력
- Eclipse
- 반복문
- oracle
- 동적계획법
- 그대로 출력하기
- db
- algoritm
- 10951
- ANSI JOIN
- 문자열
- Database
- Java
- 데이터베이스
- 알고리즘
- JOIN
- Dynamic Programming
- 데이터길이
- 오라클
- darkest dark
- Today
- Total
Cracking Code
[동적계획법 (D.P.)] 백준 2156: 포도주 시식, Java 본문
[동적계획법 (D.P.)] 백준 2156: 포도주 시식, Java
CrackCo 2020. 8. 16. 18:53
1. 접근
규칙에 따라서 가능한 계획법을 짜도록 합니다.
동적계획법에 차근차근 저장할 배열과 입력을 받아 포도주 양을 저장할 배열이 필요했습니다.
동적계획법의 배열은 dp, 포도주 양을 저장할 배열은 arr라고 합시다.
규칙1. 포도주 잔을 선택하면 그 잔에 들어있는 포도주를 모두 마시고 원래 위치에 다시 놓는다.
규칙2. 연속으로 놓여 있는 3잔을 모두 마실 수 없다.
연속으로 3잔을 안 마시기만 하면 됩니다.
차근차근 적어 나가봅니다.
dp[1] = arr[1]
dp[2] = dp[1] + arr[2]
이제 3잔 째로 갈리게 됩니다.
1번 포도주를 마시고 3번 포도주를 마시는 것과
2번 포도주를 마시고 3번 포도주를 마시는 것 중 더 마시는 것은 무엇인가?
dp[3] = Math.max(dp[1] + arr[3], arr[2] + arr[3])
4번 째 잔을 마시게 되면 조건이 하나 더 추가될 수 있습니다.
2번 포도주 까지 마신 것에 더해 4번 포도주를 마시는 것괴
1번 포도주 까지 마신 것에 더해 3번 포도주, 4번 포도주를 마시는 것이 더 마시는 것은 무엇인가?
dp[4] = Math.max(dp[1] + arr[3] + arr[4], dp[2] + arr[4])
2. 해결
위의 규칙대로 5, 6 ... 번째 잔은 4번째 잔과 마찬가지로 점화식을 세울 수 있습니다.
즉, dp[n] = Math.max(dp[n - 3] + arr[n - 1] + arr[n], dp[n - 2] + arr[n])
하지만 이렇게만 풀었을 때 문제가 발생했습니다.
연속으로 된 포도주이지만 바로 다음이 아닌 안 마시고 건너 뛸 수 있다는 사실이 있었습니다.
그렇게 되면 dp[n] 과 dp[n - 1]의 값을 비교하여 더 큰 것을 저장해야 했습니다.
3. 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n + 3];
int[] dp = new int[n + 3];
for (int i = 1; i <= n; i++) {
arr[i] = Integer.parseInt(br.readLine()); // 포도주의 양 저장
}
dp[1] = arr[1];
dp[2] = dp[1] + arr[2];
for (int i = 3; i <= n; i++) {
dp[i] = Math.max(dp[i - 2] + arr[i], dp[i - 3] + arr[i - 1] + arr[i]);
dp[i] = Math.max(dp[i - 1], dp[i]);
}
System.out.println(dp[n]);
br.close();
}
}
'Algorithms > 동적계획법 (Dynamic Programming)' 카테고리의 다른 글
[동적계획법 (D.P.)] 백준 9465: 스티커, Java (0) | 2020.08.23 |
---|---|
[동적계획법 (D.P.)] 백준 11057: 오르막 수, Java (0) | 2020.08.15 |
[동적계획법 (D.P.)] 백준 10844: 쉬운 계단 수, Java (0) | 2020.08.15 |
[동적계획법 (D.P.)] 백준 11727: 2 x N 타일링 2, Java (3) | 2020.08.08 |