알고리즘/SW Expert Academy

5215. 햄버거 다이어트

Junuuu 2022. 3. 3. 00:01
반응형

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWT-lPB6dHUDFAVT 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

문제 해석

민기가 주로 이용하는 햄버거 가게에서는 고객이 원하는 조합으로 햄버거를 만들어서 준다.


민기는 이 가게에서 자신이 먹었던 햄버거의 재료에 대한 맛을 자신의 오랜 경험을 통해 점수를 매겨놓았다.

민기의 햄버거 재료에 대한 점수와 가게에서 제공하는 재료에 대한 칼로리가 주어졌을 때

민기가 좋아하는 햄버거를 먹으면서도 다이어트에 성공할 수 있도록 정해진 칼로리 이하의 조합 중에서 민기가 가장 선호하는 햄버거를 조합해주는 프로그램을 만들어보자.


여러 재료를 조합하였을 햄버거의 선호도는 조합된 재료들의 맛에 대한 점수의 합으로 결정됩니다.

같은 재료를 여러 번 사용할 수 없으며, 햄버거의 조합의 제한은 칼로리를 제외하고는 없습니다.

 

입력

첫 번째 줄에 테스트 케이스의 수 T가 주어집니다.

 

각 테스트 케이스의 첫 번째 줄에는 재료의 수, 제한된 칼로리를 나타내는 N과 L이 공백으로 구분되어 주어집니다.

 

다음 N개의 줄에는 재료에 대한 민기의 맛에 대한 점수와 칼로리를 나타내는 T(i), K(i)가 공백으로 구분되어 주어집니다.

 

제약조건

1 ≤ N ≤ 20

1 ≤ L ≤ 10 ^4

1 ≤ Ti ≤ 10^3

1 ≤ Ki ≤ 10^3

 

출력

각 줄마다 "#T" (T는 테스트 케이스 번호)를 출력한 뒤, 주어진 제한 칼로리 이하의 조합 중에서 가장 맛에 대한 점수가 높은 햄버거의 점수를 출력한다.

 

문제 풀이 전 설계

제한된 칼로리 이하의 조합중에 가장 맛에 대한 점수가 높은 햅 버거의 점수를 출력해야 합니다.

 

맛은 좋으면서 칼로리가 낮을수록 좋습니다.

 

맛/칼로리 의 값으로 표현하면 다음과 같습니다.

100/ 200 = 0.5

300/500 = 0.4

250/300 = 0.83

500/1000 = 0.5

400/400 = 1.0

 

탐욕 법 (매 순간 가장 맛/칼로리가 높은 것을 우선적으로 선택)을 고려해보았으나 칼로리에 따라 조합된 경우가 달라져 이를 충족하지 않을 수 있어서 동작하지 않을 것 같습니다.

 

따라서 완전탐색을 조합을 사용하기로 생각했습니다.

조합의 경우에는 2^n의 시간 복잡도를 가집니다.

 

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class IngredientInfo {
	int taste = 0;
	int calorie = 0;
}

public class HamburgerDiet {

	static IngredientInfo[] ingredients;
	static int limitedCalorie;
	static int numberOfIngredient;	
	static int mostDeliciousScore;
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		int T = Integer.parseInt(br.readLine());
		for (int t = 1; t <= T; t++) {
			mostDeliciousScore = 0;
			StringTokenizer st = new StringTokenizer(br.readLine(), " ");
			numberOfIngredient = Integer.parseInt(st.nextToken());
			limitedCalorie = Integer.parseInt(st.nextToken());

			ingredients = new IngredientInfo[numberOfIngredient];

			for (int i = 0; i < numberOfIngredient; i++) {
				st = new StringTokenizer(br.readLine(), " ");
				ingredients[i] = new IngredientInfo();
				ingredients[i].taste = Integer.parseInt(st.nextToken());
				ingredients[i].calorie = Integer.parseInt(st.nextToken());
			}
			
			getMaxIngredient(0, 0, 0);
			System.out.println("#" +t +" "+mostDeliciousScore);
		}
		br.close();

	}



	static void getMaxIngredient(int idx, int curPoint, int curCal) {
		if (curCal > limitedCalorie) {
			return;
		}
		if (curPoint > mostDeliciousScore) {
			mostDeliciousScore = curPoint;
		}
		if (idx == numberOfIngredient) {
			return;
		}
		
		getMaxIngredient(idx + 1, curPoint + ingredients[idx].taste, curCal + ingredients[idx].calorie);
		getMaxIngredient(idx + 1, curPoint, curCal);

	}

}