Forming Quiz Teams
dp + bitmasking
Problem Link
#include <iostream>
#include <cstdio>
#include <math.h>
#include <cstring>
#define sf(a) scanf("%d", &a)
#define REP(i, n) for(int i = 0; i < n; i++)
using namespace std;
int n, posx, posy;
char name[21];
double dist[17][17];
double dp[1 << 16];
int xy[17][2];
double solve(int bits)
{
if(dp[bits] != -1)
return dp[bits];
if(bits == (1 << n) - 1)
return 0;
double ans = 1 << 30; // random big number
for(int i = 0; i < n; i++)
{
if(!(bits & (1 << i)))
{
for(int j = i + 1; j < n; j++)
{
if(!(bits & (1 << j)))
{
ans = min(ans, solve(bits | (1 << i) | (1 << j)) + dist[i][j]);
}
}
}
}
return dp[bits] = ans;
}
int main()
{
int k = 1;
while(true)
{
sf(n);
if(n == 0)
break;
n = 2 * n;
REP(i, n)
{
scanf("%s", name);
sf(posx);
sf(posy);
xy[i][0] = posx;
xy[i][1] = posy;
}
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
double x = (xy[i][0] - xy[j][0]) * (xy[i][0] - xy[j][0]);
double y = (xy[i][1] - xy[j][1]) * (xy[i][1] - xy[j][1]);
dist[i][j] = dist[j][i] = sqrt(x + y);
}
}
for(int i = 0; i < (1 << 16); i++)
{
dp[i] = -1;
}
double ans = solve(0);
printf("Case %d: %.2f\n",k++, ans);
}
return 0;
}
Comments
Post a Comment