치킨 배달


백준 15686: 치킨 배달

문제보기
Alt text

풀이

재귀함수를 사용하여 최대 M개의 치킨 집의 조합을 구함

  • combi(int idx, int c)
  • idx : 치킨집 위치가 담겨 있는 리스트의 인덱스 번호
  • c : 조합으로 선택되는 치킨 집을 담을 배열의 인덱스 번호

소스코드

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
	static int N;
	static int M;
	static ArrayList<Node> home;
	static ArrayList<Node> chicken;
	static Node[] sel_chicken;
	static class Node{
		int r, c;
		Node(int r, int c){
			this.r=r;
			this.c=c;
		}
		@Override
		public String toString() {
			return "Node [r=" + r + ", c=" + c + "]";
		}
		
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();	//배열크기
		M = sc.nextInt();	//최대 치킨집 개수
		int[][] map = new int[N+1][N+1];
		chicken = new ArrayList<>();	//치킨 집 위치 저장해 놓으려구
		home = new ArrayList<>();	//집 위치 저장
		
		for(int i=1; i<=N; i++) {
			for(int j=1; j<=N; j++) {
				map[i][j] = sc.nextInt();
				if(map[i][j]==2)
					chicken.add(new Node(i, j));
				else if(map[i][j]==1)
					home.add(new Node(i, j));
			}
		}
		
		//치킨 집 조합하기
		visited = new boolean[chicken.size()];
		sel_chicken = new Node[M];
		combi(0,0);
		
		System.out.println(result);
		
	}
	static boolean[] visited;
	static int result=987654321;
	static void combi(int idx, int c) {
		if(c==M) {
			int disSum=0;
			for(int i=0; i<home.size(); i++) {
				int dis = 987654321;
				int home_r = home.get(i).r;
				int home_c = home.get(i).c;
				
				for(int j=0; j<M; j++) {
					int chicken_r = sel_chicken[j].r;
					int chicken_c = sel_chicken[j].c;

					int ch_dis = Math.abs(home_r-chicken_r)+Math.abs(home_c-chicken_c);

					if(ch_dis<dis)
						dis=ch_dis;
				}
				disSum+=dis;
			}
			result=Math.min(result, disSum);
			return;
		}
		if(idx==chicken.size())
			return;
		
		sel_chicken[c] = chicken.get(idx);
		combi(idx+1, c+1);
		combi(idx+1, c);
	}
}