[백준/C++]#1106- 호텔
2022. 8. 24. 01:21ㆍ필요/코딩테스트(백준)
코드1
#include <bits/stdc++.h>
using namespace std;
int C, N;
// 비용
int cost[21];
// 고객의 수
int human[21];
// Dp의 크기
int D[1101];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> C >> N;
int inp1, inp2;
// 절대 나올 수 없는 값으로 초기화
fill(D, D+1101, 10000000);
int maxi = INT_MIN;
for (int i=0; i<N; i++) {
cin >> inp1 >> inp2;
// 가장 큰 고객의 수
maxi = max(maxi, inp2);
cost[i] = inp1;
human[i] = inp2;
// 해당 고객에 대해 가장 작은 비용의 값이 저장됨
D[human[i]] = min(D[human[i]], cost[i]);
}
// 적어도 C명이므로 최대 C+maxi까지 계산해야 전체 케이스가 보장됨
for (int i=1; i<=C+maxi; i++) {
for (int j=0; j<N; j++) {
if (i <= human[j]) continue;
D[i] = min(D[i], D[i-human[j]] + cost[j]);
}
}
// 적어도 C명이상의 최소 비용 계산
int mini = D[C];
for (int i=C+1; i<=C+maxi; i++) mini = min(mini, D[i]);
cout << mini << '\n';
return 0;
}
풀이1
D[x] = x의 고객에 대한 최소 비용
- 입력으로 제공된 해당 고객에 대해 가장 작은 비용의 값을 DP 테이블에 작성한다.
- DP[C+maxi]까지 반복문을 돌며, min(현재 DP값, 이전 DP값에서 해당 고객 뽑았을때의 비용 합)을 DP 테이블에 넣는다.
+a
- Dp 크기 1100
- C의 최댓값 1000 + 고객의 수 최댓값 100 = 1100
- 최대 Dp에 나올 수 있는 최댓값 100,000 = 1000 x 100 이므로 그보다 크게 초기화
- 초기화하는 이유는 min 연산 사용하기 위하여
- 동일 고객의 수에 대해, 가장 작은 비용의 값만 저장하면 됨
- 100명 고용하는데 10 듦 vs 20 듦
- 20 드는 경우는 절대 사용할 필요 없음
- C+maxi 까지 고려하는 이유
- D[C] 의 경우 = C명에 대한 비용
- 하지만 적어도 C명 늘리는 경우 C보다 크며, 비용이 더 작아질 수 있음
- D[C] ~ D[C + maxi] 의 경우 = 모든 경우 보장
코드2
#include <bits/stdc++.h>
using namespace std;
int C, N;
// 비용
int cost[21];
// 고객의 수
int human[21];
// Dp 크기
int D[100001];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin >> C >> N;
int inp1, inp2;
int maxi = INT_MIN;
for (int i=0; i<N; i++) {
cin >> inp1 >> inp2;
// 가장 큰 비용의 수
maxi = max(inp1, maxi);
cost[i] = inp1;
human[i] = inp2;
// 해당 비용에 대해 가장 큰 고객이 저장됨
if (D[cost[i]] != 0) D[cost[i]] = max(D[cost[i]], human[i]);
else D[cost[i]] = human[i];
}
// 최대 비용의 크기 = C x 가장 큰 비용
for (int i=1; i<=C*maxi; i++) {
for (int j=0; j<N; j++) {
if (i <= cost[j]) continue;
D[i] = max(D[i], D[i-cost[j]] + human[j]);
}
}
// C명 이상이 되자마자 index의 크기 = 최소 비용
for (int i=1; i<=C*maxi; i++) {
if (D[i]>=C) {
cout << i;
break;
}
}
return 0;
}
풀이2
D[x] = x의 비용에 대한 최대 크기의 고객
- 입력으로 제공된 해당 비용에 대해 가장 큰 고객의 값을 DP 테이블에 작성한다.
- DP[C*maxi]까지 반복문을 돌며, min(현재 DP값, 이전 DP값에서 해당 비용 지불했을 때의 고객 합)을 DP 테이블에 넣는다.
+a
- Dp의 크기 100,000
- = 최대 비용 = 100 (드는데 1명뽑음) x 1000 (명 뽑음)
- C*maxi 까지 고려하는 이유
- D[C] 의 경우 = 1명 당 1 비용 들때의 이야기
- D[C*maxi] 의 경우 = 1명 당 maxi 비용 들때의 이야기
'필요 > 코딩테스트(백준)' 카테고리의 다른 글
[백준/C++]#14719- 빗물 (0) | 2022.08.25 |
---|---|
[백준/C++]#1174, 1038- 줄어드는 수, 감소하는 수 (0) | 2022.08.21 |
[백준/C++]#13910, 13902- 개업, 개업2 (0) | 2022.08.18 |
[백준/C++]#1654 - 랜선 자르기 (0) | 2022.08.15 |
[백준/C++]#1967 - 트리의 지름 (0) | 2021.02.19 |