📄문제
카운슬러로 일하고 있는 현수는 오늘부터 N+1일째 되는 날 휴가를 가기 위해서, 남은 N일 동안 최대한 많은 상담을 해서 휴가비를 넉넉히 만들어 휴가를 떠나려 한다. 현수가 다니는 회사에 하루에 하나씩 서로 다른 사람의 상담이 예약되어 있다. 각각의 상담은 상담을 완료하는데 걸리는 날수 T와 상담을 했을 때 받을 수 있는 금액 P로 이루어져 있다.
만약 N = 7이고, 아래와 같이 예약이 잡혀있다면
1일에 잡혀있는 상담은 총 4일이 걸리며, 상담했을 때 받을 수 있는 금액은 20이다. 만약 1일에 예약된 상담을 하면 4일까지는 상담을 할 수가 없다.
하나의 상담이 하루를 넘어가는 경우가 많기 때문에 현수는 예약된 모든 상담을 혼자 할 수 없어 최대 이익이 나는 상담 스케줄을 짜기로 했다.
휴가를 떠나기 전에 할 수 있는 상담의 최대 이익은 1일, 5일, 7일에 있는 상담을 하는 것이며, 이때의 이익은 20+30+10=60이다. 현수가 휴가를 가기 위해 얻을 수 있는 최대 수익을 구하는 프로그램을 작성하시오.
⬇️ 입력
첫째 줄에 N (1 ≤ N ≤ 15)이 주어진다.
둘째 줄부터 1일부터 N일까지 순서대로 주어진다. (1 ≤ T ≤ 7, 1 ≤ P ≤ 100)
7 4 20 2 10 3 15 3 20 2 30 2 20 1 10 |
⬆️ 출력
첫째 줄에 현수가 얻을 수 있는 최대 이익을 출력한다.
60 |
📝 풀이
#include<stdio.h>
int N, T[16], P[16], res = 0;
void DFS(int L, int sum)
{
// 모든 선택을 완료하였다면?
if (L == N + 1)
if (sum > res)
res = sum;
else
{
// 현재까지 일정 + 다음 일정이 N + 1보다 작다면, 상담을 시도
if (L + T[L] <= N + 1)
DFS(L + T[L], sum + P[L]);
// 상담을 하지 않는 경우도 재귀로 호출
DFS(L + 1, sum);
}
}
int main()
{
scanf_s("%d", &N);
for (int i = 1; i <= N; i++)
scanf_s("%d %d", &T[i], &P[i]);
DFS(1, 0);
printf("%d\n", res);
return 0;
}
- 수익을 sum으로 누적하여 깊게 재귀를 호출하여 해결합니다.
- L == N + 1은 마지막 날 까지 선택을 시도하였다는 뜻으로, 누적 수익을 갱신합니다.
- L + T[L] <= N + 1은 현재부터 T[L]에 해당하는 일이 끝나는 날이 N+1을 초과하지 않는다는 뜻으로, 해당 일을 수행할 수 있습니다. L을 넘겨줄 때 T[L]이 끝나는 날짜로 넘깁니다.
- 그 외에도 DFS(L + 1, sum)을 통해 L + 1에 해당하는 일을 하지 않을때를 고려하여 추가로 호출합니다.
'algorithms (C++)' 카테고리의 다른 글
[C++] 피자 배달 거리(DFS) 🔥 (0) | 2023.10.20 |
---|---|
[C++] 수식만들기 (1) | 2023.10.19 |
[C++] 복면산 SEND+MORE=MONEY 🔥 (0) | 2023.10.19 |
[C++] 순열구하기(DFS : Depth First Search) 🔥 (0) | 2023.10.19 |
[C++] 벨만-포드 알고리즘 ⭐ (2) | 2023.10.19 |