문제 링크
https://www.acmicpc.net/problem/17208
문제
중간고사 종료를 기념해 계획 없이 돈을 쓰던 영석이는 안타깝게도 통장 잔고가 100원도 남지 않게 되었고, 결국 영석이는 카우버거 주방 알바를 하기로 했다. 카우버거는 치즈버거와 감자튀김을 파는 중앙대학교의 유명한 음식점이다.
알바 첫날, 영석이가 주방에 들어선 순간 그는 매우 중요한 사실을 깨달았다. 사실 그는 치즈버거는 물론이고 감자튀김도 만들 줄 모른다는 것이다. 이때 다행히도 주방에는 누군가 만들어둔 치즈버거와 감자튀김이 몇 개 남아있었고, 영석이는 현재 들어온 주문을 이걸 이용해 처리하기로 했다.
모든 주문은 각각 치즈버거 요구 개수와 감자튀김 요구 개수를 의미하는 2개의 정수로 이루어진다. 어떤 주문을 처리하기 위해서는 치즈버거와 감자튀김을 정확히 그 주문에서 요구하는 만큼 써야 한다. 또한 주문이 들어온 순서와 관계없이 원하는 주문을 선택해 처리할 수 있으며, 한번 처리한 주문은 사라지므로 같은 주문을 다시 처리하는 것은 불가능하다.
아쉽게도 주방에 남아있는 것이 많지 않기 때문에 어떤 주문은 처리하지 못할 수도 있다. 최선의 방법으로 주문을 선택해 처리한다면 최대 몇 개의 주문을 처리할 수 있을까?
입력
첫째 줄에 주문의 수 N(1 ≤ N ≤ 100), 주방에 남은 치즈버거 개수 M(1 ≤ M ≤ 300), 주방에 남은 감자튀김 개수 K(1 ≤ K ≤ 300)가 주어진다.
둘째 줄부터 N개의 줄에는 주문 내용을 의미하는 두 정수 x, y (1 ≤ x, y ≤ 300)가 주어진다. x는 치즈버거 요구 개수, y는 감자튀김 요구 개수를 나타낸다.
출력
주방에 남은 치즈버거와 감자튀김을 사용해 처리할 수 있는 최대 주문 개수를 출력한다.
예제 입력 1
4 3 4
2 5
1 2
3 3
2 1
예제 출력 1
2
2개의 주문을 처리하는 방법으로 2번째 주문과 4번째 주문을 선택해 처리하는 방법이 있다.
3개 이상의 주문을 처리하는 방법은 없으므로 최대로 처리가능한 주문 개수는 2이다.
예제 입력 2
5 5 5
5 5
7 3
2 9
8 5
2 9
예제 출력 2
1
오직 1번째 주문만 처리할 수 있다.
예제 입력 3
3 4 4
1 1
1 1
1 2
예제 출력 3
3
모든 주문을 처리할 수 있다.
알고리즘 분류
- 배낭 문제
풀이
DP[100][300][300]이라는 3차원 배열을 선언한다. 이것은 i번째 주문까지 탐색했을 때, j개의 치즈버거와 k개의 감자튀김으로 최대 몇 개의 주문을 받을 수 있는지를 의미한다.
3중 for문을 사용하여 i번째 주문까지 탐색했을 때 j개의 치즈버거와 k개의 감자튀김으로 받을 수 있는 주문의 최댓값을 기록해주면서 최대로 받을 수 있는 주문의 개수를 계속 갱신해준다.
코드
#include <iostream>
#include <string>
#include <cmath>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <ctime>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <climits>
#define FASTIO cin.tie(NULL); cout.tie(NULL); ios::sync_with_stdio(false);
#define MAX_N 101
#define MAX_MK 301
#define LL long long
#define INF 1e9
using namespace std;
int N, M, K;
int X[MAX_N], Y[MAX_N];
int DP[MAX_N][MAX_MK][MAX_MK];
int Answer = 0;
void Input() {
cin >> N >> M >> K;
for (int i = 1; i <= N; i++) {
cin >> X[i] >> Y[i];
}
}
void Settings() {
for (int i = 1; i <= N; i++) {
for (int j = M; j >= 0; j--) {
for (int k = K; k >= 0; k--) {
if ((j - X[i] >= 0) && (k - Y[i] >= 0)) {
DP[i][j][k] = max(DP[i - 1][j][k], DP[i - 1][j - X[i]][k - Y[i]] + 1);
}
else {
DP[i][j][k] = DP[i - 1][j][k];
}
Answer = max(Answer, DP[i][j][k]);
}
}
}
}
void Find_Answer() {
cout << Answer << "\n";
}
int main() {
FASTIO
Input();
Settings();
Find_Answer();
return 0;
}
'BOJ > Gold' 카테고리의 다른 글
[BOJ/Gold 4] 백준 6066 Buying Hay(C++) (0) | 2022.04.17 |
---|---|
[BOJ/Gold 4] 백준 23061 백남이의 여행 준비(C++) (0) | 2022.04.17 |
[BOJ/Gold 5] 백준 22115 창영이와 커피(C++) (0) | 2022.04.16 |
[BOJ/Gold 5] 백준 17845 수강 과목(C++) (0) | 2022.04.16 |
[BOJ/Gold 5] 백준 1106 호텔(C++) (0) | 2022.04.15 |