TSP 문제로 볼 수 있다. 


문제에 모든 경우의 수를 확인하면 된다고 적혀있으므로 모두 구하는 방법도 있고


비트마스크로 dp를 사용하는 방법도 있다.


모든 경우의 수는 next_permutation을 사용하면 쉽게 가능하지만 2200ms나 걸리고 dp를 사용하면 6ms가 나온다.


dp테이블은 d[현재위치][현재 방문상태 비트마스크] 형식이다.



<순열 코드>


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
#include <iostream>
#include <algorithm>
using namespace std;
 
typedef long long ll;
struct po {
    int x, y;
};
 
int t, n;
int pm[12];
po a[12];
 
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> t;
    for (int tc = 1; tc <= t; ++tc) {
        cin >> n;
        int ans = 2e9;
        cin >> a[0].x >> a[0].y >> a[n + 1].x >> a[n + 1].y;
        for (int i = 1; i <= n; ++i) {
            cin >> a[i].x >> a[i].y;
            pm[i] = i;
        }
        pm[n + 1= n + 1;
        do {
            int sum = 0;
            for (int i = 1; i <= n + 1++i) 
                sum += abs(a[pm[i]].x - a[pm[i - 1]].x) + abs(a[pm[i]].y - a[pm[i - 1]].y);
            ans = min(ans, sum);
        } while (next_permutation(pm + 1, pm + 1 + n));
        cout << "#" << tc << " " << ans << '\n';
    }
    return 0;
}
cs



<dp 코드>


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
#include <iostream>
#include <algorithm>
#include <memory.h>
using namespace std;
 
typedef long long ll;
struct po {
    int x, y;
};
 
int t, n;
int d[11][1 << 11], e;
int dist[12][12];
po a[12];
// cur_position, bitmask
int dp(int f, int x) {
    int &ret = d[f][x];
    if (ret != -1return ret;
    if (x == e) 
        return dist[f][n + 1];
    ret = 2e9;
    for (int i = 1; i <= n; ++i) {
        if (x&(1 << i)) continue;
        ret = min(ret, dp(i, x | (1 << i)) + dist[f][i]);
    }
    return ret;
}
 
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
    cin >> t;
    for (int tc = 1; tc <= t; ++tc) {
        memset(d, -1sizeof(d));
        cin >> n;
        int ans = 2e9;
        e = (1 << (n + 1)) - 1;
        cin >> a[0].x >> a[0].y >> a[n + 1].x >> a[n + 1].y;
        for (int i = 1; i <= n; ++i) 
            cin >> a[i].x >> a[i].y;
        for (int i = 0; i < n + 2++i) for (int j = 0; j < n + 2++j)
            dist[i][j] = abs(a[i].x - a[j].x) + abs(a[i].y - a[j].y);
        
        cout << "#" << tc << " " << dp(01<< '\n';
    }
    return 0;
}
cs


'SWEA' 카테고리의 다른 글

1244. 최대 상금  (0) 2018.08.29
1245. 균형점  (0) 2018.08.29
1251. 하나로  (0) 2018.08.29
2105. 디저트 카페  (0) 2018.08.29
3752. 가능한 시험 점수  (0) 2018.08.29

+ Recent posts