https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWT-lPB6dHUDFAVT
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
평소 햄버거를 좋아하던 민기는 최근 부쩍 늘어난 살 때문에 걱정이 많다.
그렇다고 햄버거를 포기할 수 없었던 민기는 햄버거의 맛은 최대한 유지하면서 정해진 칼로리를 넘지 않는 햄버거를 주문하여 먹으려고 한다.
민기가 주로 이용하는 햄버거 가게에서는 고객이 원하는 조합으로 햄버거를 만들어서 준다.
하지만 재료는 미리 만들어서 준비해놓기 때문에 조합에 들어가는 재료를 잘라서 조합해주지는 않고, 재료를 선택하면 준비해놓은 재료를 그대로 사용하여 조합해준다.
민기는 이 가게에서 자신이 먹었던 햄버거의 재료에 대한 맛을 자신의 오랜 경험을 통해 점수를 매겨놓았다.
민기의 햄버거 재료에 대한 점수와 가게에서 제공하는 재료에 대한 칼로리가 주어졌을 때,
민기가 좋아하는 햄버거를 먹으면서도 다이어트에 성공할 수 있도록 정해진 칼로리 이하의 조합 중에서 민기가 가장 선호하는 햄버거를 조합해주는 프로그램을 만들어보자.
(단 여러 재료를 조합하였을 햄버거의 선호도는 조합된 재료들의 맛에 대한 점수의 합으로 결정되고, 같은 재료를 여러 번 사용할 수 없으며, 햄버거의 조합의 제한은 칼로리를 제외하고는 없다.)
[입력]
첫 번째 줄에 테스트 케이스의 수 T가 주어진다.
각 테스트 케이스의 첫 번째 줄에는 재료의 수, 제한 칼로리를 나타내는 N, L(1 ≤ N ≤ 20, 1 ≤ L ≤ 104)가 공백으로 구분되어 주어진다.
다음 N개의 줄에는 재료에 대한 민기의 맛에 대한 점수와 칼로리를 나타내는 Ti, Ki(1 ≤ Ti ≤ 103, 1 ≤ Ki ≤ 103)가 공백으로 구분되어 주어진다.
[출력]
각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 주어진 제한 칼로리 이하의 조합중에서 가장 맛에 대한 점수가 높은 햄버거의 점수를 출력한다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Burger {
static int N; // 재료의 수
static int T; // 제한 칼로리
static int Max; // 제한 칼로리 이하의 조합중 최대 맛 총점
// 매개변수
// int sum_k = 선택한 원소들의 칼로리 합계
// int[][] num = 선택 대상 배열
// int cnt = 선택 수행 횟수
// boolean[] isSelected = 선택 True&False 저장 배열
public static void powerSet(int sum_k, int[][] num, int cnt, boolean[] isSelected) {
if (cnt == N) { // 재료의 수만큼 선택하는 행위를 완료
if (sum_k > T) // 제한 칼로리 이상->중지
return; // 맛 총점 계산과 Max 갱신 코드를 수행하지 않도록 return
// 맛총점 계산, Max 갱신
int sum_t = 0; // 맛 총점
for (int i = 0; i < N; i++) { // isSelected를 탐색해서
if (isSelected[i]) { // 선택된 원소일 경우
sum_t += num[i][0]; // 맛총점에 점수 add
}
}
if (Max <= sum_t) // 맛 총점이 max 이상일 경우
Max = sum_t; // max를 맛 총점으로 갱신
return; // cnt가 N이므로 더이상 powerset을 호출하지 않도록 return
}
// cnt가 N이 아니면 선택, 비선택 powerset 호출
isSelected[cnt] = true;
powerSet(sum_k + num[cnt][1], num, cnt + 1, isSelected); // 선택한 경우이므로 칼로리 합계에 선택된 원소의 칼로리 add
isSelected[cnt] = false;
powerSet(sum_k, num, cnt + 1, isSelected); // 비선택한 경우이므로 칼로리 합계는 그대로
}
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
int TC = Integer.parseInt(br.readLine()); // Testcase 수 입력
for (int t = 1; t <= TC; t++) {
Max = Integer.MIN_VALUE; // Testcase 마다 Max를 Integer의 최솟값으로 갱신
sb.append("#" + t + " ");
String str = br.readLine();
st = new StringTokenizer(str, " ");
N = Integer.parseInt(st.nextToken()); // 재료의 수 입력
T = Integer.parseInt(st.nextToken()); // 제한 칼로리 수 입력
// tk 배열에 재료의 수만큼 맛 점수와 칼로리를 입력받음
int[][] tk = new int[N][2];
for (int n = 0; n < N; n++) {
str = br.readLine();
st = new StringTokenizer(str, " ");
tk[n][0] = Integer.parseInt(st.nextToken());
tk[n][1] = Integer.parseInt(st.nextToken());
}
powerSet(0, tk, 0, new boolean[N]); //칼로리 합계 0, cnt 0으로 powerset 호출
sb.append(Max + "\n"); //sb에 갱신된 Max값과 개행문자 삽입
}
System.out.println(sb);
}
}
'문제해결 > SWExpertAcademy' 카테고리의 다른 글
| SWExpertAcademy 9229번-한빈이와 Spot Mart(JAVA) (0) | 2021.08.09 |
|---|---|
| SWExpertAcademy 1228번-암호문1(JAVA) (0) | 2021.08.09 |
| SWExpertAcademy 1861번-정사각형 방(JAVA) (0) | 2021.08.06 |
| SWExpertAcademy 3499번-퍼펙트 셔플(JAVA) (0) | 2021.08.06 |
| SWExpertAcademy 1225번-암호생성기(JAVA) (0) | 2021.08.05 |




