오늘은 여기까지
[swea/4012] 요리사 - Java 자바 본문
https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AWIeUtVakTMDFAVH
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!
swexpertacademy.com
문제 설명
두 명의 손님에게 음식을 제공하려고 한다.
두 명의 손님은 식성이 비슷하기 때문에, 최대한 비슷한 맛의 음식을 만들어 내야 한다.
N개의 식재료가 있다.
식재료들을 각각 N / 2개씩 나누어 두 개의 요리를 하려고 한다. (N은 짝수이다.)
이때, 각각의 음식을 A음식, B음식이라고 하자.
비슷한 맛의 음식을 만들기 위해서는 A음식과 B음식의 맛의 차이가 최소가 되도록 재료를 배분해야 한다.
음식의 맛은 음식을 구성하는 식재료들의 조합에 따라 다르게 된다.
식재료 i는 식재료 j와 같이 요리하게 되면 궁합이 잘 맞아 시너지 Sij가 발생한다. (1 ≤ i ≤ N, 1 ≤ j ≤ N, i ≠ j)
각 음식의 맛은 음식을 구성하는 식재료들로부터 발생하는 시너지 Sij들의 합이다.
식재료 i를 식재료 j와 같이 요리하게 되면 발생하는 시너지 Sij의 정보가 주어지고, 가지고 있는 식재료를 이용해 A음식과 B음식을 만들 때, 두 음식 간의 맛의 차이가 최소가 되는 경우를 찾고 그 최솟값을 정답으로 출력하는 프로그램을 작성하라.
N = 4인 예를 생각해보자. 시너지 Sij는 [Table 1]과 같이 주어진다.
식재료 1과 식재료 2를 A음식으로 만들고 식재료 3과 식재료 4를 B음식으로 만드는 경우를 생각하자.
1) 식재료 1을 식재료 2와 같이 요리했을 때 발생하는 시너지 S12는 5이다.
2) 식재료 2를 식재료 1과 같이 요리했을 때 발생하는 시너지 S21는 4이다.
3) A음식의 맛은 5 + 4 = 9가 된다.
4) 식재료 3을 식재료 4와 같이 요리했을 때 발생하는 시너지 S34는 3이다.
5) 식재료 4를 식재료 3과 같이 요리했을 때 발생하는 시너지 S43은 3이다.
6) B음식의 맛은 3 + 3 = 6이 된다.
따라서, 두 음식 간의 맛의 차이는 |9 – 6| = 3이 된다.
식재료 2와 식재료 4를 A음식으로 만들고 식재료 1과 식재료 3을 B음식으로 만드는 경우를 생각하자.
두 음식간의 맛의 차이는 |3 – 5| = 2가 된다.
이 경우가 A음식과 B음식 간의 맛의 차이가 최소인 경우이다.
다른 경우에서는 맛의 차이가 2보다 작을 수 없다.
따라서, 본 예의 정답은 2가 된다.
입력
입력의 맨 첫 줄에는 총 테스트 케이스의 개수 T가 주어지고,
그 다음 줄부터 T개의 테스트 케이스가 주어진다.
각 테스트 케이스의 첫 번째 줄에는 식재료의 수 N이 주어진다.
다음 N개의 줄에는 N * N개의 시너지 Sij값들이 주어진다. i와 j가 서로 같은 경우는 0으로 주어진다.
출력
테스트 케이스 개수만큼 T개의 줄에 각각의 테스트 케이스에 대한 답을 출력한다.
각 줄은 "#t"로 시작하고 공백을 하나 둔 다음 정답을 출력한다. (t 는 1부터 시작하는 테스트 케이스의 번호이다.)
정답은 두 음식 간의 맛의 차이가 최소가 되도록 A음식과 B음식을 만들었을 때 그 차이 값이다.
풀이
예시가 N = 4일때로 주어져서 처음에 조금 헤맸는데, N = 6인 경우를 생각해보자.
A음식은 1, 2, 4를 선택, B음식은 3, 5, 6을 선택하면 `syn[1][2] + syn[1][4] + syn[2][4] + syn[2][1] + syn[4][1] + syn[4][2]`와 ` syn[3][5] + syn[3][6] + syn[5][6] + syn[5][3] + syn[6][3] + syn[6][5]`의 차이의 절대값을 구한다. 이렇게 모든 조합에 대한 시너지를 계산해서 최소값을 구한다.
숫자를 돌면서 A음식 조합을 고른다 visited는 A음식, not visited는 B음식으로 가정한다.
A음식을 고르면 나머지는 자동으로 B음식이므로 n/2개의 재료로 음식을 만든다.
전체코드
import java.util.*;
import java.io.*;
public class Main {
static int[][] syn;
static boolean[] visited;
static int N;
static int answer;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for (int t = 1; t <= T; t++) {
N = Integer.parseInt(br.readLine());
syn = new int[N][N];
visited = new boolean[N];
answer = Integer.MAX_VALUE;
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
syn[i][j] = Integer.parseInt(st.nextToken());
}
}
dfs(0, 0);
System.out.println("#" + t + " " + answer);
}
}
public static void combination(int idx, int cnt) {
if (cnt == N/2) {
answer = Math.min(answer, diff());
return;
}
for (int i = idx; i < N; i++) {
visited[i] = true;
combination(i + 1, cnt + 1);
visited[i] = false;
}
}
public static int diff() {
int first = 0;
int second = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (i == j) continue;
if (visited[i] && visited[j]) {
first += syn[i][j];
}
else if (!visited[i] && !visited[j]) {
second += syn[i][j];
}
}
}
return Math.abs(first - second);
}
}
'Problem Solving' 카테고리의 다른 글
[백준/13549] 숨바꼭질 3 - Java 자바 (0) | 2024.11.19 |
---|---|
[swea/20019] 회문의 회문 - Java 자바 (1) | 2024.11.17 |
[프로그래머스] 조이스틱 - Java 자바 (0) | 2024.11.15 |
[프로그래머스] 체육복 - Java 자바 (2) | 2024.11.14 |
[백준/2579] 계단 오르기 - Java 자바 (2) | 2024.11.13 |