题目链接: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;
}