题目链接:https://vjudge.net/contest/307763#problem/A
题目大意:

思路:




我这里把i枚举的是最大值:

#include <bits/stdc++.h>
using namespace std;

double x[20], y[20];
double dp[1<<(17)];
const double INF = 10e7;

double dis(int i, int j)
{
    return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}

int main()
{
    int n, CUT=1;
    while(~scanf("%d",&n), n)
    {
        n*=2;
        string name;
        for(int i=0;i<n;i++)
        {
            cin>>name>>x[i]>>y[i];
        }
        dp[0]=0;
        for(int s=0;s<(1<<n);s++)
        {
            int i,j;
            if(s!=0)
            {
                dp[s]=INF;
            }
            for(i=n;i>=1;i--)//枚举i,因为i最大,和j<i位i交换,所以不能取到0
            {
                if(s&(1<<i))//第i位存在
                {
                    break;
                }
            }
            for(j=i-1;j>=0;j--)
            {
                //取j+1位,判断第j个元素是否存在
                if(s&(1<<j))
                {
                    //s^(j)=把第k位变为0, dp[s^(1<<i)^(1<<j)]=去掉i,j后的集合
                    dp[s]=min(dp[s], dis(i, j)+dp[s^(1<<i)^(1<<j)]);
                }
            }
        }
        printf("Case %d: %.2f\n",CUT++, dp[(1<<n)-1]);

    }

    return 0;
}