반응형
문제
https://www.acmicpc.net/problem/2156
2156번: 포도주 시식
효주는 포도주 시식회에 갔다. 그 곳에 갔더니, 테이블 위에 다양한 포도주가 들어있는 포도주 잔이 일렬로 놓여 있었다. 효주는 포도주 시식을 하려고 하는데, 여기에는 다음과 같은 두 가지 규칙이 있다. 포도주 잔을 선택하면 그 잔에 들어있는 포도주는 모두 마셔야 하고, 마신 후에는 원래 위치에 다시 놓아야 한다. 연속으로 놓여 있는 3잔을 모두 마실 수는 없다. 효주는 될 수 있는 대로 많은 양의 포도주를 맛보기 위해서 어떤 포도주 잔을 선택해야 할지 고
www.acmicpc.net
풀이
세 가지 포도주를 연속적으로 선택할 수 없으므로 n 번째에서 선택을 세 가지 경우로 나눈다.
0이면 포도주를 선택 하지 않는 경우,
1이면 포도주를 1번 연속 선택한 (n) 경우,
2이면 포도주를 2번 연속 선택한 (n - 1, n) 경우로 나눈다.
n 번째에서 세 가지 경우 중 가장 큰 값으로 선택을 하면 된다.
arr[n] = n번째 포도주 양, dp[n][state] = n번째 포도주잔과 state(0, 1, 2) 라고 하면 다음의 점화식을 구할 수 있다.
dp[n][0] = max{
dp[n-1][0],
dp[n-1][1],
dp[n-1[2]
}
dp[n][1] = dp[n - 1][0] + arr[n]
dp[n][2] = dp[n - 1][1] + arr[n]
세 가지 경우 중 최댓값을 찾으면 된다.
코드
탑다운 방식
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
32
33
34
35
36
37
|
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int arr[10001];
int dp[10001][3];
int result;
// 2: 2번 연속 선택, 1: 1번 연속 선택, 0: 선택 X
int f(int n, int state)
{
if (n <= 0) return 0;
if (dp[n][state]) return dp[n][state];
if (state == 0) return dp[n][state] = max(f(n - 1, 0), max(f(n - 1, 1), f(n - 1, 2)));
else if (state == 1) return dp[n][state] = f(n - 1, 0) + arr[n];
else return dp[n][state] = f(n - 1, 1) + arr[n];
}
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++) cin >> arr[i];
result = max(f(n, 0), max(f(n, 1), f(n, 2)));
cout << result;
return 0;
}
|
cs |
바텀업 방식
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
32
33
|
#include <iostream>
#include <algorithm>
using namespace std;
int n;
int arr[10001];
int dp[10001][3];
int result;
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++) cin >> arr[i];
dp[1][0] = 0; dp[1][1] = arr[1]; dp[1][2] = 0;
for (int i = 2; 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] + arr[i];
dp[i][2] = dp[i - 1][1] + arr[i];
}
result = max(dp[n][0], max(dp[n][1], dp[n][2]));
cout << result;
return 0;
}
|
cs |
반응형
'BOJ' 카테고리의 다른 글
백준 11055 - 가장 큰 증가 부분 수열 (0) | 2019.07.16 |
---|---|
백준 11053 - 가장 긴 증가하는 부분 수열 (0) | 2019.07.14 |
백준 10451 - 순열 사이클 (0) | 2019.07.11 |
백준 1707 - 이분 그래프 (0) | 2019.07.10 |
백준 11057 - 오르막 수 (0) | 2019.07.08 |