728x90
https://www.acmicpc.net/problem/19942
19942번: 다이어트
식재료 N개 중에서 몇 개를 선택해서 이들의 영양분(단백질, 탄수화물, 지방, 비타민)이 일정 이상이 되어야 한다. 아래 표에 제시된 6가지의 식재료 중에서 몇 개를 선택해서 이들의 영양분의 각
www.acmicpc.net
728x90
메모리: 37,444 KB , 시간: 368 ms
사용 알고리즘: 백트래킹, 브루트포스 알고리즘
import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.StringTokenizer; public class Main { static int N; // N := 식재료의 개수 static int[] minIgdt; // 최소 영양성분 static int[][] igdt; // 식재료 정보 static boolean[] visited; // 식재료 포함 여부 static int resultPrice = -1; // 최소 가격 static ArrayList<ArrayList<Integer>> resultList = new ArrayList<>(); // 최소 가격을 만족하는 재료 리스트들 public static void main(String[] args) throws Exception{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; // 입력 N = Integer.parseInt(br.readLine()); minIgdt = new int[4]; st = new StringTokenizer(br.readLine()); for (int i = 0; i < 4; i++) { minIgdt[i] = Integer.parseInt(st.nextToken()); } igdt = new int[N + 1][5]; for (int i = 1; i <= N; i++) { st = new StringTokenizer(br.readLine()); for (int j = 0; j < 5; j++) { igdt[i][j] = Integer.parseInt(st.nextToken()); } } visited = new boolean[N + 1]; isInclude(1); // 출력 if(resultPrice == -1) System.out.println(-1); else { // 정답 후보 정렬 ArrayList<Integer> resultArray = getFirstArray(); StringBuilder result = new StringBuilder(); result.append(resultPrice + "\n"); for (int i = 0; i < resultArray.size(); i++) { result.append(resultArray.get(i) + " "); } System.out.println(result); } } static void isInclude(int order) { // order번째 식재료를 포함할 것인지 결정 if(order == N) { check(); visited[order] = true; check(); visited[order] = false; return; } // order번째 재료 포함하지 않는 경우 isInclude(order + 1); // order번째 재료 포함하는 경우 visited[order] = true; isInclude(order + 1); visited[order] = false; } static void check() { // 현재 재료로 최소 영양분을 만족하는지 확인 int[] sumIgdt = new int[5]; ArrayList<Integer> list = new ArrayList<>(); for (int i = 1; i <= N; i++) { if(visited[i]) { // 포함하는 재료라면 list.add(i); for (int j = 0; j < 5; j++) { sumIgdt[j] += igdt[i][j]; // 최소 영양분 합을 구해줌 } } } boolean flag = true; for (int i = 0; i < 4; i++) { if(sumIgdt[i] < minIgdt[i]) flag = false; // 최소 영양분을 만족시키지 못한 경우 } if(flag) { // 최소 영양분을 만족시켰다면 if(resultPrice == -1) { // 처음 만족시키는 경우라면 resultPrice = sumIgdt[4]; resultList.add(list); } else if (resultPrice == sumIgdt[4]) { // 현재 최소 가격과 동일할 경우 resultList.add(list); } else if (resultPrice > sumIgdt[4]) { // 현재 리스트가 최소 가격일 경우 resultPrice = sumIgdt[4]; resultList.clear(); resultList.add(list); } } } static ArrayList<Integer> getFirstArray() { // 최소 가격 재료 리스트 중 사전 순으로 첫번째 오는 것 반환 ArrayList<Integer> ret = resultList.get(0); ArrayList<Integer> now; for (int i = 1; i < resultList.size(); i++) { now = resultList.get(i); boolean flag = false; int index = ret.size() > now.size() ? now.size() : ret.size(); // 더 짧은 리스트까지 비교 for (int j = 0; j < index; j++) { if(ret.get(j) > now.get(j)) { // now가 사전 순 더 앞 flag = true; ret = now; break; } else if (ret.get(j) < now.get(j)) { // ret이 사전순 더 앞 flag = true; break; } } // now가 더 짧은 배열이고 now와 ret의 앞부분이 같다면 if(!flag && index == now.size()) ret = now; } return ret; } }
728x90
'Problem Solving > BOJ' 카테고리의 다른 글
[백준, BOJ 1548] 부분 삼각 수열 (java) (0) | 2023.11.23 |
---|---|
[백준, BOJ 2281] 데스노트 (java) (0) | 2023.11.21 |
[백준, BOJ 1720] 타일 코드 (java) (1) | 2023.11.14 |
[백준, BOJ 27653] 최소 트리 분할 (java) (1) | 2023.11.09 |
[백준, BOJ 2487] 섞기 수열 (java) (0) | 2023.11.08 |