문제 링크 : https://www.acmicpc.net/problem/15686


해결 방법)


풀고나서 다른 해결방법들을 보니까 대게 비슷하게 푼것같다. 

그래도 내가 푼 아이디어를 풀어보고자 한다. (누군가에게는 도움이 되겟지하는 생각에)

치킨집 고르는 경우 즉 M개(1개의 치킨집, 2개의 치킨집, 3개의 치킨집 ...... M개의 치킨집) 에서 모든 집들과의 거리중 최소거리만 구하여 이 최소거리의 합들이 우리가 구하고자하는 도시의 치킨거리값이 되는 것이다.


그런데 우리는 1개를 어떻게고르고 2개를 어떻게고르고에 대한 아이디어가 없당 ㅜ 이것은 재귀적으로 상황을 두개 만들어 주면 된다. 있고, 없고의 두가지상황인데 A,B,C의 치킨집이있다고하면,

A 있고 B 있고, C 없고

A 없고 B 있고 C 없고 .... 요론식으로 하다보면 모든 경우의수를 찾을 수 있다는 느낌을 받을 수 있다.

즉 각 치킨집마다 있고 없고의 상황 두가지를 만들어서 치킨집을 먼저 고를 수 있다.


이제 골라진 치킨집이 1개일때,2개일때 ,3개일때, 4개일때..... M개 이하 일때 마다 치킨 거리 총합을 알아야지 도시의 치킨거리를 알 수 가있는데 어떻게 골라진 치킨집 개수마다 그 치킨거리 총합을 알아낼 것인가가 문제이다.


이 해결방법은 모든 집마다 거리를 구하는데 골라진 집들과의 사이를 구하면서 최소값을 각 집마다 구해나가는 것이다.

우리는 각치킨집마다 경우를 있고,없고의 두가지 경우를 만들었는데, 이때 치킨집이 있다라면 이 치킨집은 골라진녀석이고 따로 골라졌다라는 표식을 남겨두면 나중에 골라진 치킨집에대해 거리값을 구해나갈수 있다.

따라서 골라진 치킨집과 모든 집들사이의 거리를 구할 수 있게되고 당연히 최소값도 구하게되면서 이 최소값들의 총합이 결국엔 우리가 구하는 답이 된다.


또 참고로 최대 M개라고해서 M개를 골랐을때만 왜 조건을 거냐라고 말할 수 있는데, 어차피 FOR문을 돌면 각집이 치킨집들 중 최소값만 지니기 때문에 하나의 치킨집만 선택된경우도 자연스레 포함이 되어 모든 경우를 내포하기때문이다.


소스코드)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int ans = 987654321// 도시의 치킨거리
int M;
int visit[13];
vector<pair<intint>> home; // 집좌표
vector<pair<intint>> chicken; // 치킨 좌표
int csize;
int min(int a, int b) { return a < b ? a : b; }
void solve(int inow, int cnt_now)
{
    if (cnt_now == M) // 최대 M개를 고를때
    {
        int d; // 두점사이의 거리
        int x1, x2;
        int y1, y2;
        int tmp = 0;
        int homesize = home.size();
        for (int i = 0; i < homesize; i++)
        {
            int minnum = 987654321;
            for (int j = 0; j < csize; j++)
            {
                if (visit[j]) 
                {
                    d = abs(home[i].first - chicken[j].first) + abs(home[i].second - chicken[j].second);
                    if (minnum > d)
                        minnum = d;
                }
            }
            tmp += minnum;
            
        }
        ans = min(ans, tmp); //도시치킨거리 갱신
        return;
    }
    if (inow >= csize) return
    visit[inow] = 1;// 현재 치킨집 선택
    solve(inow + 1, cnt_now + 1); 
    visit[inow] = 0
    solve(inow + 1, cnt_now);
}
int main()
{
    int N;
    int num;
    cin >> N >> M;
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= N; j++)
        {
            scanf("%d"&num);
            if (num == 1)
            {
                home.push_back({ i,j });
            }
            else if (num == 2)
            {
                chicken.push_back({ i,j });
            }
        }
    }
    csize = chicken.size();
    solve(00);
    printf("%d\n",ans);
}
cs


반응형

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

2448번 별 찍기 - 11  (0) 2018.11.12
1966번 프린터 큐  (0) 2018.10.28
7576번 토마토  (0) 2018.10.24
2839 설탕배달  (0) 2018.10.19
14891번 톱니바퀴  (0) 2018.10.15

+ Recent posts