Algorithm
SW Expert Academy_벌꿀 채취
Young_J
2020. 9. 29. 17:19
//알고리즘
1. 모든 경우를 다 해봐야하는 완탐문제
2. A일꾼의 일한 곳을 기준으로 B일꾼은 A일꾼이 일하지 않은 곳 전부 탐색.
3. 부분집합을 사용하여 나올 수 있는 가장 큰 수 저장.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class 벌꿀채취 {
static int T, N, M, C, map[][], max;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
T = Integer.parseInt(br.readLine());
for (int tc = 1; tc <= T; tc++) {
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
map = new int[N][N];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
for (int j = 0; j < N; j++) {
map[i][j] = Integer.parseInt(st.nextToken());
}
}
int ans = 0;
int[] arr = new int[M];
boolean[] v;
for (int r = 0; r < N; r++) {
for (int c = 0; c <= N - M; c++) {
int sum = 0; // 합계
// A일꾼
for (int i = 0; i < M; i++) {
arr[i] = map[r][c + i];
}
v = new boolean[M];
max = 0;
powerSet(0, arr, v);
sum = max;
// B일꾼 -> A일꾼이 일한 곳 제외.
for (int i = 0; i < N; i++) {
for (int j = 0; j <= N - M; j++) {
// if(i==r) continue;
if (i == r && (!check(j, c) || !check(c, j)))
continue;
for (int k = 0; k < M; k++) {
arr[k] = map[i][j + k];
}
v = new boolean[M];
max = 0;
powerSet(0, arr, v);
sum += max;
ans = Math.max(ans, sum);
sum -= max;
}
}
}
}
System.out.printf("#%d %d\n", tc, ans);
// print(map);
}
}
private static void powerSet(int idx, int[] arr, boolean[] v) {
if (idx == M) {
int sum = 0;
for (int i = 0; i < v.length; i++) {
if (v[i])
sum += arr[i];
}
if (sum <= C) {
int powsum = 0;
for (int i = 0; i < v.length; i++) {
if (v[i])
powsum += Math.pow(arr[i], 2);
}
max = Math.max(max, powsum);
}
return;
}
v[idx] = true;
powerSet(idx + 1, arr, v);
v[idx] = false;
powerSet(idx + 1, arr, v);
}
private static boolean check(int ac, int c) {
for (int i = 0; i < M; i++) {
if (c == ac + i)
return false;
}
return true;
}
private static void print(int[][] map) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
}
}