https://www.acmicpc.net/problem/15686
15686번: 치킨 배달
크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸
www.acmicpc.net
Brute Force 문제이다.
Brute Force란? 가능한 모든 조합를 구해서 답을 구하는 기법이다.
주어진 치킨집의 개수 중 m개에 해당하는 치킨집 조합을 모두 구한 후 그에 따른 거리 합의 최솟값을 구해주면 된다.
시간복잡도를 계산하기 위해 가장 worst case를 계산해보면
13개의 치킨집 중 6개를 선택하고 13!/7!6! 그 모든 조합에 집들(최대 100개)마다 최소 거리를 구해야하기 때문에
(13C6)*6*100 = 1,029,600이 된다.
다행히 1억번보다 작기 때문에 시간 내에 여유롭게 풀이 가능하다.
#include <cstdio>
#include <limits.h>
#include <algorithm>
#include <stdlib.h>
#include <utility>
#include <memory.h>
#include <vector>
using namespace std;
//INPUT이 클 경우 파일로 받는다.
FILE* in = fopen("input.txt", "r");
//문제에서 주어진 조건
#define N_MAX 50
#define M_MAX 13
int n, m;
int map[N_MAX][N_MAX];
int path[M_MAX];
int ans = INT_MAX;
vector<pair<int, int>> home, chicken;
int dx[4] = { 0, 0, -1, 1 };
int dy[4] = { -1, 1, 0, 0 };
using namespace std;
//거리를 계산하는 함수
int calc_dis(int x, int y, int a, int b) {
return abs(x - a) + abs(y - b);
}
//BRUTE FORCE를 위한 DFS
void dfs(int idx, int selected) {
//M개의 조합이 완성되면 거리 최솟값의 합을 구한다.
if (selected == m)
{
int ret = 0;
for (int i = 0; i < home.size(); i++)
{
int x = home[i].first; int y = home[i].second;
int tmp = calc_dis(x, y, chicken[path[0]].first, chicken[path[0]].second);
for (int j = 1; j < m; j++)
{
tmp = min(tmp, calc_dis(x, y, chicken[path[j]].first, chicken[path[j]].second));
}
ret += tmp;
}
//기존의 거리 합보다 작을 경우 갱신
if (ret < ans)
ans = ret;
return;
}
//모두 순회하면 종료
if (idx == chicken.size())
return;
//경로를 표시하기 위한 배열
path[selected] = idx;
dfs(idx + 1, selected + 1);
dfs(idx + 1, selected);
}
int main() {
fscanf(in, "%d %d", &n, &m);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
fscanf(in, "%d", &map[i][j]);
int idx = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
//값이 1일 경우 집 좌표로 PUSH
if (map[i][j] == 1)
{
home.push_back(make_pair(i, j));
}
//값이 2일 경우 치킨 좌표로 PUSH
else if (map[i][j] == 2)
{
chicken.push_back(make_pair(i, j));
}
dfs(0, 0);
printf("%d", ans);
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 13460번 구슬 탈출 2 C/C++ 풀이 (0) | 2020.08.13 |
---|---|
백준 14888번 연산자 끼워넣기 C/C++ 풀이 (0) | 2020.08.09 |
백준 17144 미세먼지 안녕! C/C++ 풀이 (0) | 2020.08.06 |
백준 14891번 톱니바퀴 C/C++ 풀이 (0) | 2020.08.05 |
백준 14503번 문제 로봇 청소기 C/C++ 풀이 (0) | 2020.08.04 |