본문 바로가기

Algorithm/DP(Dynamic Programing)

(C++) - 백준(BOJ) 13302번 : 리조트

반응형

https://www.acmicpc.net/problem/13302

 

13302번: 리조트

수영이는 여름방학을 맞이하여 많은 놀이 시설이 있는 KOI 리조트에 놀러가려고 한다. 리조트의 하루 이용권의 가격은 만원이다. 하지만 리조트의 규모는 상상을 초월하여 모든 시설을 충분히 즐기기 위해서는 하루로는 터무니없이 부족하다. 그래서 많은 이용객들은 3일 이상 연속으로 이용하기도 한다. KOI 리조트에서는 3일 연속 이용권을 할인된 가격 이만오천원에, 연속 5일권은 삼만칠천원에 판매하고 있다. 게다가 연속 3일권, 연속 5일권에는 쿠폰이 각각 1장,

www.acmicpc.net

Top-Down dp문제였습니다.

 

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
int n, m;
int d[101][101];
bool b_day[101];//검은날(수영이 쉬는 날)설정용 배열
 
//경우의 수
//1.하루 이용권 쓸 경우
//2.연속 3일권 쓸 경우
//3.연속 5일권 쓸 경우
//4.수영이 쉬는날
 
//현재날 : day, 남은 쿠폰 : coupon, ret은 가격
int resort(int day,int coupon) {
    //쿠폰은 몇장이 남았는지 상관이 없다. 
    //루프 탈출은 방학날이 끝났으면 ㅂㅂ
 
    //먼저 기저값 설정
    if (day >= n+1return 0;
 
    int &ret = d[day][coupon];
 
    //메모이제이션
    if (ret != -1return ret;
 
    //쉬는날이면 아무것도 하지않는다.
    if (b_day[day]) {
        ret = resort(day + 1, coupon);
    }
    else {
        ret = 0x3f3f3f3f;
        //하루 이용권
        ret = min(ret, resort(day + 1, coupon) + 10000);
        //연속 3일권
        ret = min(ret, resort(day + 3, coupon + 1+ 25000);
        //연속 5일권
        ret = min(ret, resort(day + 5, coupon + 2+ 37000);
 
        //쿠폰 3장 이상이면 쿠폰을 하루 이용권으로 교환 비용:0원
        if (coupon >= 3) {
            ret = min(ret, resort(day + 1, coupon - 3));
        }
    }
    return ret;
}
int main() {
    cin >> n >> m;
    while(m--){
        int x;
        cin >> x;
        b_day[x] = true;
    }
    memset(d, -1sizeof(d));
 
    cout << resort(10<<'\n';
}
cs