题意:集合上的动态规划,刘汝佳上书的相似题目,d (s ) 表示是把集合S中的元素两两配对后的最小距离和。
d(s)= min { |Pi Pj| + d ( s - {i} - {j})};
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 10;
const int INF = 1 << 30;
double dp[1<<(2*MAXN)];
int cas,x[MAXN*2],y[MAXN*2],cnt;
double dis(int i,int j){
return sqrt(pow((double)(x[i]-x[j]),2)+pow((double)(y[i]-y[j]),2));
}
int main(){
cnt = 1;
while (scanf("%d%*c",&cas) != EOF){
if (!cas)
break;
int nn = 2 * cas;
char name[25];
for (int i = 0; i < nn; i++)
scanf("%s%d%d",name,&x[i],&y[i]);
for (int s = 0; s < (1 << nn); s++){
int i,j;
dp[s] = INF;
bool flag = 1;
for (i = 0; i < nn; i++)
if (s & (1<<i))
break;
for (j = i + 1; j < nn; j++)
if (s & (1<<j))
dp[s] = min ( dp[s], dis ( i, j ) + dp[s ^ ( 1 << i ) ^ ( 1 << j )] ), flag = 0;
if (flag)
dp[s] = 0;
}
printf("Case %d: %.2lf\n",cnt++,dp[(1<<nn) - 1]);
}
return 0;
}