Uva_000011
The key to this question is to express the group status. After reading other people's problem-solving reports, we found that since N is very small, we can use an integer binary to represent the group status, if this parameter is set to 1, it indicates that the team member has not been grouped. Status transfer means that the group can be enumerated.
I personally feel that it is better to use the memory-based search.
#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAXD 70000
#define MAXN 20
#define INF 1000000000
int N;
double x[MAXN], y[MAXN], f[MAXD];
char b[30];
double sqr(double a, double b)
{
return (a - b) * (a - b);
}
int init()
{
int i;
scanf("%d", &N);
N *= 2;
if(!N)
return 0;
for(i = 0; i < N; i ++)
scanf("%s%lf%lf", b, &x[i], &y[i]);
return 1;
}
double dp(int st)
{
int i, j;
double min = INF, temp;
if(f[st] > -1)
return f[st];
for(i = 0; i < N; i ++)
if((1 << i) & st)
for(j = i + 1; j < N; j ++)
if((1 << j) & st)
{
temp = dp(st ^ (1 << i) ^ (1 << j)) + f[(1 << i) + (1 << j)];
if(temp < min)
min = temp;
}
return f[st] = min;
}
void solve()
{
int i, j;
double res;
f[0] = 0;
for(i = 1; i < (1 << N); i ++)
f[i] = -2;
for(i = 0; i < N; i ++)
for(j = i + 1; j < N; j ++)
f[(1 << i) + (1 << j)] = sqrt(sqr(x[i], x[j]) + sqr(y[i], y[j]));
res = dp((1 << N) - 1);
printf("%.2f\n", res);
}
int main()
{
int t = 0;
while(init())
{
printf("Case %d: ", ++ t);
solve();
}
return 0;
}