알고리즘/백준

백준 15686 치킨 배달

https://www.acmicpc.net/problem/15686

 

15686번: 치킨 배달

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸, 왼쪽에서부터 c번째 칸을 의미한다. r과 c는 1부터 시작한다. 이 도시에 사는 사람들은 치킨을 매우 좋아한다. 따라서, 사람들은 "치킨 거리"라는 말을 주로 사용한다. 치킨 거리는 집과 가장 가까운 치킨집 사이의 거리이다. 즉, 치킨 거리는

www.acmicpc.net

  • 치킨집을 선택, 재귀를 사용
  • 집에서 선택한 치킨집 중에서 거리가 최소인 것을 선택
  • 위 에서 구한 거리를 모두 더한다
/*
	치킨집을 m개 만큼 선택
	각 집에서 치킨집을 선택
	거리의 최솟값

	main
		입력
	sol(index, cnt)
		if cnt == M
			for 집 갯수
				각 집에서 치킨집까지의 거리중 가장 작은 값 ret에 더함
			ans <- ret최솟값
			return
		pick_shop.push_back
		sol(index+1, cnt+1)
		pick_shop.pop_back
		sol(index+1, cnt)
*/
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int N, M;
int map[50][50];
vector<pair<int,int>> house;
vector<pair<int, int>> shop;
vector<pair<int, int>> shop_pick;
const int INF= 987654321;
int ans = INF;
void sol(int index, int cnt)
{
	if (cnt == M)
	{
		int ret = 0;
		for (int i = 0; i < house.size(); i++)
		{
			int dist = 999;
			for (int j = 0; j < shop_pick.size(); j++)
			{
				int tmp = abs(shop_pick[j].first - house[i].first) + abs(shop_pick[j].second - house[i].second);
				dist = min(dist, tmp);
			}
			ret += dist;
		}
		ans = min(ret, ans);
		return;
	}
	if (index >= shop.size())
	{
		return;
	}
	shop_pick.push_back(shop[index]);
	sol(index + 1, cnt + 1);
	shop_pick.pop_back();
	sol(index + 1, cnt);
}
int main() {
	cin >> N >> M;
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			cin >> map[i][j];
			if (map[i][j] == 1) house.push_back({ i,j });
			else if (map[i][j] == 2) shop.push_back({ i,j });
		}
	}
	sol(0,0);
	cout << ans;
}

'알고리즘 > 백준' 카테고리의 다른 글

[백준 1405] 미친 로봇  (0) 2020.08.15
백준 16234 인구 이동  (0) 2020.03.13
백준 15685 드래곤 커브  (0) 2020.03.13
15684 사다리 조작  (0) 2020.03.13
15683 감시  (0) 2020.03.12