본문 바로가기

개발/알고리즘

백준 알고리즘 15686

입력 : 도시의 크기와 유지할 치킨집의 최대 개수 M, 도시 정보

출력 : 치킨집의 최대 개수(M)만큼을 제외하고 모두 폐점시켰을 때 치킨거리의 최소값

 

풀이

1. 입력받을 때 치킨집과 가정집의 위치를 따로 벡터에 저장한다.

2. 모든 치킨집 중 M개를 고르는 재귀함수를 구현해 M개를 고른 뒤 치킨거리를 구한다.

3. 치킨집을 고른 결과가 중복이 되지 않도록 재귀함수를 구현한다. 중복처리 안하면 시간초과남

 

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>

using namespace std;

struct Point{
	int x;
	int y;
};

Point getPoint(int x, int y){
	Point result;
	result.x = x;
	result.y = y;
	
	return result;
}

int city[51][51];
vector<Point> chicken;
bool checkChicken[13];
vector<int> selectedChicken;
vector<Point> house;
int M;

int getChickenDistance(){
	int houseNum = house.size();
	int result = 0;
	
	for(int i=0; i<houseNum; i++){
		int minChickenDistance = 2000;
		for(int j=0; j<M; j++){
			int temp = abs(house[i].x - chicken[selectedChicken[j]].x) + abs(house[i].y - chicken[selectedChicken[j]].y);

			if(temp < minChickenDistance)
				minChickenDistance = temp;
		}
		result += minChickenDistance;
	}
	
	return result;
}

int selectChicken(int n){
	int selectedChickenNum = selectedChicken.size();
	
	if(M == selectedChicken.size())
		return getChickenDistance();
	
	int chickenNum = chicken.size();
	int min = 100000;
	
	for(int i=n; i<=chickenNum - (M-selectedChickenNum); i++) {
		if(checkChicken[i])
			continue;
			
		selectedChicken.push_back(i);
		checkChicken[i] = true;
		
		int result = selectChicken(i+1);
		if(result < min)
			min = result;
		
		selectedChicken.pop_back();
		checkChicken[i] = false;
	}
	
	return min;
}

int main() {
	int N;
	
	scanf("%d %d\n", &N, &M);
	
	for(int i=0; i<N; i++){
		for(int j=0; j<N; j++){
			scanf("%d ", &city[i][j]);
			
			if(city[i][j] == 2)
				chicken.push_back(getPoint(i, j));
			else if(city[i][j] == 1)
				house.push_back(getPoint(i, j));
		}
	}
	
	printf("%d", selectChicken(0));
	
	return 0;
}

'개발 > 알고리즘' 카테고리의 다른 글

백준 알고리즘 14890  (0) 2019.04.12
백준 알고리즘 15685  (0) 2019.04.12
백준 알고리즘 14888  (0) 2019.02.28
백준 알고리즘 14503  (0) 2019.02.21
백준 알고리즘 14891  (0) 2019.02.20