P1433 吃奶酪

\(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;
}
posted @ 2020-10-14 13:38  yys_c  阅读(149)  评论(0编辑  收藏  举报