UVa 10911 - Forming Quiz Teams
传送门
UVa 10911 - Forming Quiz Teams
题意
给出n * 2个点,要求配出n组点,使每组点的距离之和最短。
思路
小白上的例题,不过因为涉及到位运算,脑子有点转不过来,只能勉强理解。
把每种状态压缩,然后DP。
代码
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
struct POINT
{
int x, y;
}point[20];
double dp[(1 << 20)];
double Dis(int i, int j)
{
return hypot(point[i].x - point[j].x, point[i].y - point[j].y);
}
int main()
{
//freopen("input.txt", "r", stdin);
int i, j, n, cases = 0;
char str[200];
while (scanf("%d", &n), n)
{
n = n * 2;
for (i = 0; i < n; i++)
scanf("%s%d%d", str, &point[i].x, &point[i].y);
dp[0] = 0;
for (int s = 1; s < (1 << n); s++)
{
dp[s] = INF;
for (i = 0; i < n; i++)
if (s & (1 << i))
break;
for (j = i + 1; j < n; j++)
if (s & (1 << j))
dp[s] = min(dp[s], Dis(i, j) + dp[s ^ (1 << i) ^ (1 << j)]);
}
printf("Case %d: %.2lf\n",++cases, dp[(1 << n) - 1]);
}
return 0;
}