๋ชฉ์ฐจ
1. ๋ฌธ์ ์ค๋ช
2. ํผ ์๋ฆฌ ์ค๋ช
3. ์ฝ๋
1. ๋ฌธ์ ์ค๋ช
https://www.acmicpc.net/problem/14889
2. ํผ ์๋ฆฌ ์ค๋ช
์ผ๋จ ๋๋ ์ด๊ฑฐ ๋ต์ง ๋ดค๋ค.
(1) ํ์ ์กฐํฉ์ผ๋ก ๋ฐ์ผ๋ก ๋๋๋ค. -> (2) ๊ฐ ํ ๋ฉค๋ฒ๊ฐ์ ์๋์ง ๊ณ์ฐ -> (3) ์ฐจ ๊ตฌํด์ ๊ทธ ์ฐจ๊ฐ ์ง๊ธ๊น์ง์ ๊ฐ ์ค ์ต์์ผ ๊ฒฝ์ฐ ๊ฐฑ์
์๊ฑฐ๊น์ง๋ ์๊ฐ์ ํ๋๋ฐ, (2)๋ ์กฐํฉ์ผ๋ก ์คํํธํ ๋ด์์ 2๋ช ์ฉ ์ง์ ์ก์์ ๊ฐ์ ๊ณ์ฐ ํด์ผ ํ๋ค๊ณ ์๊ฐํ๋ค. ๊ทธ๋ฌ๋ฉด ๊ฒฝ์ฐ์ ์๊ฐ ๊ธฐํ๊ธ์์ ์ผ๋ก ๋์ด๋๋ค.
ํ์ง๋ง ๋ต์ ๋ณด๋, ์๋์ง๋ 2๋ช
์ฉ ์ง์ ์ง์ด์ ๊ทธ ๋ ์ฌ์ด์ ์๋์ง๋ง ๋ค ๋ํ๋ ๊ฒ์ด ์๋์๊ณ ,
(๋์ ์๊ฐ: A,B,C,D๊ฐ ์คํํธ ํ์ด๋ฉด A,B / C,D ๋ก ์ง ์ง์ด์ ๊ฐ ์๋์ง ๊ณ์ฐํ๊ณ ๊ทธ ์๋์ง์ ์ดํฉ์ด ์คํํธํ์ ์ดํฉ )
๊ทผ๋ฐ ์ด๊ฒ ์๋๋ผ ๊ทธ๋ฅ ๊ฐ์ํ ๋ฉค๋ฒ๋ผ๋ฆฌ ์ผ์ด๋๋ ๋ชจ๋ ์๋์ง์ ์ดํฉ์ด ๋ต์ด์๋ค.
(A,B,C,D๊ฐ ์คํํธ ํ์ด๋ฉด , A ์ B,C,D์ ์๋์ง, B ์ C,D์ ์๋์ง, C์ D์ ์๋์ง์ ์ดํฉ )
-> ์ด๊ฑธ ์กฐํฉ์ผ๋ก ๊ตฌํด์ผ ํ๋ค๊ณ ์๊ฐํ๋๋ฐ, ๊ทธ๋ฅ 2์ฐจ์ ๋ฐฐ์ด ๋๋ฉด์ ๋ชจ๋ ์๋์ง๋ฅผ ๋ํ๋ฉด ๋์๋ค.
3. ์ฝ๋
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Array;
import java.util.*;
// 14889๋ฒ ์คํํธ์ ๋งํฌ
public class Main {
// ์ฌ์ฉํ ๊ธฐ์ : ์กฐํฉ
// ํธ๋ ๋ฐฉ๋ฒ
// (A) ๋ฐ์ผ๋ก ํ ๋๋๊ธฐ -> ๋ฐฉ๋ฌธ ๋ฐฐ์ด๋ก ๊ฐ๋ผ์ง Aํ, Bํ ๋ฉค๋ฒ ๋ช
์
// (B) Aํ ์ด ์๋์ง, Bํ ์ด ์๋์ง ๊ณ์ฐ -> ๊ฐ ํ๋ณ๋ก ์กฐํฉ
// (C) ๋ฅ๋ ฅ์น ์ฐจ์ด๊ฐ ์ต์์ธ์ง ํ์ธ, ํ์ฌ๊น์ง ์ต์๋ฉด ๋ฅ๋ ฅ์น ์ฐจ์ด ๋ณ์ ๊ฐฑ์
// * ์
๋ ฅ ๋ฐ๊ธฐ ์ํ ๋ณ์
static int N;
static int [][] arr;
// * ๋ฐ ๋๋๊ธฐ ์ํ ๋ฐฉ๋ฌธ ๋ฐฐ์ด
static boolean [] isVisited;
// * ๋๋ ์ง ํ์ฉ -> ์ ์ ๋ด๊ธฐ/ ์ ์๋ค์ ๋ฐฉ๋ฌธ ๋ฐฐ์ด
// * ์ต์ ์๋์ง ์ฐจ
static int subtraction = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 1) ์
๋ ฅ ๋ฐ๊ธฐ
N = Integer.parseInt(br.readLine());
arr = new int[N+1][N+1];
isVisited = new boolean[N+1];
for (int i = 1; i <= N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 1; j <= N; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
selectHalf(1,1);
System.out.println(subtraction);
}
// 2) ๋ฐ์ผ๋ก ๋๋๊ธฐ
public static void selectHalf(int cnt, int start) {
if(cnt > N/2){
calculate();
return;
}
for (int i = start; i <= N; i++) {
if(!isVisited[start]){
isVisited[start] = true;
selectHalf(cnt+1, i+1);
isVisited[start] = false;
}
}
}
// true ํ์์ 2๋ช
์ ๋ฝ์์ ์๋์ง๋ฅผ ๊ณ์ฐํ ํ tureTeamAmount์ ์ง์ด๋ฃ๋๋ค.
// false ํ์์ 2๋ช
์ ๋ฝ์์ ์๋์ง๋ฅผ ๊ณ์ฐํ ํ falseTeamAmount์ ์ง์ด๋ฃ๋๋ค.
public static void calculate() {
int trueTeam = 0;
int falseTeam = 0;
for (int i = 1; i <= N -1 ; i++) {
for (int j = i+1; j <= N; j++) {
if( isVisited[i] && isVisited[j]){
trueTeam += arr[i][j] + arr[j][i];
}
if(!isVisited[i] && !isVisited[j]){
falseTeam += arr[i][j] + arr[j][i];
}
}
}
subtraction = Math.min(subtraction, Math.abs(trueTeam - falseTeam));
}
}