(f(i, j))表示走到第j个点,走过的路径情况是i的所有走法的集合,存储最短距离属性。
(f(i, j) = min {f(i, j), f(i - { j }, k)}, k = 0, 1, ..., n - 1)其中k是当前路径i下走到j的上一个点。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
const int N = 16, M = 1 << 16;
const double INF = 0x7f7f7f7f7f7f7f7f;
struct Node{
double x, y;
}a[N];
double f[M][N];
int n;
double calc(int p, int q){
double dx = a[p].x - a[q].x;
double dy = a[p].y - a[q].y;
return sqrt(dx * dx + dy * dy);
}
int main(){
cin >> n;
a[0] = {0, 0};
for(int i = 1; i <= n; i ++) cin >> a[i].x >> a[i].y;
++ n;
memset(f, 0x7f, sizeof f);
f[1][0] = 0;
for(int i = 0; i < 1 << n; i ++)
for(int j = 0; j < n; j ++)
if(i >> j & 1) // 当前路径存在j点
for(int k = 0; k < n; k ++)
if(i - (1 << j) >> k & 1) // 走到j的上一个点是k
f[i][j] = min(f[i][j], f[i - (1 << j)][k] + calc(k, j));
double res = INF;
for(int i = 0; i < n; i ++)
res = min(res, f[(1 << n) - 1][i]);
printf("%.2lf", res);
return 0;
}