P1433 吃乳酪
阿新 • • 發佈:2020-10-14
\(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; }