(부분 집합 풀이)
import java.io.*;
import java.util.*;
public class Main {
static int[][] arr;
static int ans = Integer.MAX_VALUE;
static boolean[] visited;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(br.readLine());
arr = new int[n][n];
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
visited = new boolean[n];
backtracking(n, 0);
bw.write(ans+"");
br.close();
bw.close();
}
private static void backtracking(int n, int depth) {
if(depth == n){
int start = 0;
int link = 0;
for (int i = 0; i < n; i++) {
if(visited[i]){
start++;
}else{
link++;
}
}
if(start >= 1 && link >= 1){
int diff = solve(n);
ans = Math.min(ans, diff);
}
return;
}
visited[depth] = true;
backtracking(n, depth+1);
visited[depth] = false;
backtracking(n, depth+1);
}
private static int solve(int n) {
int start = 0;
int link = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
if(visited[i] && visited[j]){
start += arr[i][j] + arr[j][i];
}
if(!visited[i] && !visited[j]){
link += arr[i][j] + arr[j][i];
}
}
}
return Math.abs(start - link);
}
}
(조합 풀이)
import java.io.*;
import java.util.*;
public class Main {
static int[][] arr;
static int ans = Integer.MAX_VALUE;
static boolean[] visited;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(br.readLine());
arr = new int[n][n];
for (int i = 0; i < n; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
for (int j = 0; j < n; j++) {
arr[i][j] = Integer.parseInt(st.nextToken());
}
}
visited = new boolean[n];
for (int i = 1; i <= n; i++) {
backtracking(n, 0, 0, i);
}
bw.write(ans+"");
br.close();
bw.close();
}
private static void backtracking(int n, int depth, int now, int pick) {
if(depth == pick){
int start = 0;
int link = 0;
for (int i = 0; i < n; i++) {
if(visited[i]){
start++;
}else{
link++;
}
}
if(start >= 1 && link >= 1){
int diff = solve(n);
ans = Math.min(ans, diff);
}
return;
}
for (int i = now; i < n; i++) {
if(!visited[i]){
visited[i] = true;
backtracking(n, depth+1, i+1, pick);
visited[i] = false;
}
}
}
private static int solve(int n) {
int start = 0;
int link = 0;
for (int i = 0; i < n; i++) {
for (int j = i+1; j < n; j++) {
if(visited[i] && visited[j]){
start += arr[i][j] + arr[j][i];
}
if(!visited[i] && !visited[j]){
link += arr[i][j] + arr[j][i];
}
}
}
return Math.abs(start - link);
}
}