https://www.acmicpc.net/problem/2961
2961번: 도영이가 만든 맛있는 음식
첫째 줄에 재료의 개수 N(1 ≤ N ≤ 10)이 주어진다. 다음 N개 줄에는 그 재료의 신맛과 쓴맛이 공백으로 구분되어 주어진다. 모든 재료를 사용해서 요리를 만들었을 때, 그 요리의 신맛과 쓴맛은
www.acmicpc.net
코드설명
일반적인 완전탐색 문제로, DFS를 통하여 만들 수 있는 음식의 조합을 구한다음에 신맛과 쓴맛의 차이점을 구하면 됩니다.
처음에 계속해서 틀려서 어떤이유인지 확인결과 level > 1 초과로 코딩을 해놓아서 올바르게 나오지 않았습니다.
if( level >= 1) { result = Math.min(result, Math.abs(sourTaste - hurtTaste)); }
또 처음에 제가 작성한 코드처럼 조합을 구해서 진행하는방식이 아닌 다른방식도 같이 작성해보았습니다.
코드
조합을 통해 결과를 구함
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static String T; public static int N; public static Node[] Node; public static boolean[] visited; public static long result = Integer.MAX_VALUE; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); Node = new Node[N]; visited = new boolean[N]; for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); int a = Integer.parseInt(st.nextToken()); int b = Integer.parseInt(st.nextToken()); Node[i] = new Node(a, b); } simulate(0, 1, 0, 0); System.out.println(result); } public static void simulate(int idx, long sourTaste, int hurtTaste, int level) { if(level == N) { result = Math.min(result, Math.abs(sourTaste - hurtTaste)); return ; } if( level >= 1) { result = Math.min(result, Math.abs(sourTaste - hurtTaste)); } for(int i=idx;i<N;i++) { if(visited[i] == true) continue; Node temp = Node[i]; int sourTasteTemp = temp.sourTaste; int hurtTasteTemp = temp.hurtTaste; visited[i] = true; simulate(i + 1, sourTaste * sourTasteTemp , hurtTaste + hurtTasteTemp, level + 1); visited[i] = false; } } } class Node{ int sourTaste; //신맛 int hurtTaste; //쓴맛 public Node(int sourTaste, int hurtTaste) { this.sourTaste = sourTaste; this.hurtTaste = hurtTaste; } }
DFS 분기처리를 통해 구함( 조합을 구한것과 마찬가지자만 방향이 살짝 다르다. )
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.*; public class Main { public static String T; public static int N; public static Node[] Node; public static boolean[] visited; public static long result = Integer.MAX_VALUE; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); Node = new Node[N]; visited = new boolean[N]; for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); int a = Integer.parseInt(st.nextToken()); int b = Integer.parseInt(st.nextToken()); Node[i] = new Node(a, b); } simulate(0); System.out.println(result); } public static void simulate(int level) { if(level == N) { int sour = 1; int hurt = 0; for(int i=0;i<N;i++) { if(visited[i] == true) { sour *= Node[i].sourTaste; hurt += Node[i].hurtTaste; } } if(sour!= 1 && hurt != 0) result = Math.min(result, Math.abs(sour - hurt)); return ; } visited[level] = true; simulate(level + 1); visited[level] = false; simulate(level + 1); } } class Node{ int sourTaste; //신맛 int hurtTaste; //쓴맛 public Node(int sourTaste, int hurtTaste) { this.sourTaste = sourTaste; this.hurtTaste = hurtTaste; } }
정답코드3입니다. 가장 짧은 코드
package Main; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.StringTokenizer; public class Main { public static int C, N, H, W, K, M; public static int answer = 0; public static int[][] food; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); food = new int[N][2]; for(int i=0;i<N; i++) { st = new StringTokenizer(br.readLine()); int a = Integer.parseInt(st.nextToken()); int b = Integer.parseInt(st.nextToken()); food[i][0] = a; food[i][1] = b; } System.out.println(bruteforce(0, 0, 0)); } public static long bruteforce(int depth, int now, int visited) { if(depth == N) { return calculate(visited); } long ret = Long.MAX_VALUE; ret = bruteforce(depth + 1, now + 1, visited + (1 << now)); ret = Math.min(ret, bruteforce(depth + 1, now + 1, visited)); return ret; } public static long calculate(int visited) { boolean isContainsZeroFood = true; long aTaste = 1, bTaste = 0; for(int i=0; i<N; i++) { if( (visited & (1<<i)) > 0) { isContainsZeroFood = false; aTaste *= food[i][0]; bTaste += food[i][1]; } } if(isContainsZeroFood) return Long.MAX_VALUE; return Math.abs(aTaste - bTaste); } }
'알고리즘 > 백준' 카테고리의 다른 글
[백준] 15661 링크와 스타트 - 완전탐색 (DFS) JAVA (0) | 2023.07.16 |
---|---|
[백준] 2615 오목 - 완전탐색 (DFS) JAVA (0) | 2023.07.16 |
[백준] 14620 꽃길 - 완전탐색 JAVA (0) | 2023.07.15 |
[백준] 16508 전공책 - 완전탐색 + 문자열(알파벳) JAVA (0) | 2023.07.14 |
[백준] 16937 두 스티커 - 완전탐색 + 아이디어 JAVA (0) | 2023.07.14 |