SWEA 5215 - 햄버거 다이어트
Updated:
Java
5215 번 - 햄버거 다이어트
문제
민기의 햄버거 재료에 대한 점수와 가게에서 제공하는 재료에 대한 칼로리가 주어졌을 때,
민기가 좋아하는 햄버거를 먹으면서도 다이어트에 성공할 수 있도록 정해진 칼로리 이하의 조합 중에서 민기가 가장 선호하는 햄버거를 조합해주는 프로그램을 만들어보자.
접근 방법
DFS를 통하여 부분 집합을 구한다.
부분 집합이란, [1,2,3,4,5]라는 원소가 있으면
[1], [2], [3], [4], [5], [1,2], [1,3] ~ [1,2,3,4,5] 와 같이 부분 집합을 구하는 것이며,
이를 이용하여 재료의 부분 집합을 구하여 그 재료들의 칼로리 합이 제한 조건 보다 낮으면 그 재료들의 점수 합을 구한다.
점수 합들의 최댓값을 구하여 출력한다.
구현
ArrayList와 Pair를 이용하여 각 재료들의 정보를 저장한다.
DFS를 통하여 n개의 재료들을 뽑을지 말지 정한다.
이를 sel[] 배열을 통하여 나타내며, sel 인덱스는 ArrayList의 인덱스와 일치시켜 만약 sel[i]가 true이면 이 인덱스를 통해 ArrayList에 접근하여 재료 정보를 얻는다.
위 과정을 설명하면,
- DFS(0,0)으로 첫번째 재료부터 탐색을 한다.
- 현재 재료를 선택하는 경우와 선택하지 않는 경우를 각각 호출한다.
- 만약 재료를 선택하는 경우, 현재 재료의 칼로리를 합하여 다음 DFS의 인자로 넘겨준다
- 총 칼로리의 합이 L을 넘어가면, 더 이상 탐색할 가치가 없으므로 종료한다.
- n개의 재료의 선택 유무를 다 확인하면, 이제 선택 된 재료들의 점수를 합한다.
- 합한 점수의 최댓값을 갱신한다
코드
import java.io.*;
import java.util.*;
class Solution {
static boolean sel[];
static int n, l, result = 0;
static ArrayList<Pair> mtr;// material
public static void main(String []args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk;
int tc = stoi(br.readLine());
for(int idx = 1; idx <= tc; idx++) {
result = 0;
mtr = new ArrayList<>();
stk = new StringTokenizer(br.readLine());
n = stoi(stk.nextToken());
l = stoi(stk.nextToken());
// 재료 추가
for(int i = 0; i < n; i++) {
stk = new StringTokenizer(br.readLine());
mtr.add(new Pair(stoi(stk.nextToken()), stoi(stk.nextToken())));
}
sel = new boolean[n];
DFS(0,0);
System.out.println("#" + idx + " " + result);
}
br.close();
}
static void DFS(int lv, int Cal) {
// 조기 종료 조건. 제한 칼로리 보다 선택한 재료들의 칼로리가 높으면 종료
if(Cal > l) {
return;
}
if(lv == n) { // n개의 재료 선택 유무가 완료되었을 시
int sumC = 0;
for(int i = 0; i < n; i++){
if(sel[i])
sumC += mtr.get(i).a; // 선택한 재료들의 점수 합을 구한다.
}
result = Math.max(result, sumC); // 점수 합이 기존 합보다 클 시
return;
}
sel[lv] = true; // 현재 재료 하나를 선택 하였을 시
DFS(lv + 1, Cal + mtr.get(lv).b); // 선택한 재료의 칼로리를 추가하여 다음 재료 선택 유무 호출
sel[lv] = false; // 재료를 선택하지 않음
DFS(lv + 1, Cal); // 선택하지 않은 재료이므로, 칼로리 추가 없이 다음 재료 선택 유무 확인
}
static class Pair {
public int a; // 점수
public int b; // 칼로리
Pair(int a, int b){
this.a = a;
this.b = b;
}
@Override // Pair가 정상적으로 동작하는지 확인하는 toString
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(a).append(" ").append(b);
return sb.toString();
}
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}
총평
난이도
⭐★★★★
후기
각 테스트 케이스를 시도하는 반복문 초기에 ArrayList와 Result를 초기화 해주지 않아 3번이나 틀렸다.
이를 주의깊게 볼 필요가 있다.
개선할 점
없