UVa 10911 - Forming Quiz Teams

  题目大意:给出2*n个点,将这些点配成n对,使得所有点对中两点的距离之和尽量小。

  用一个整数的二进制形式表示一个集合的子集,以每个集合为状态进行状态转移。具体参见《算法竞赛入门经典》9.5。

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>
 4 #include <cfloat>
 5 using namespace std;
 6 
 7 struct Point
 8 {
 9     int x, y;
10 } point[20];
11 double dp[1<<16+10];
12 
13 double dis(int a, int b)
14 {
15     int x_diff = point[a].x - point[b].x;
16     int y_diff = point[a].y - point[b].y;
17     return sqrt(x_diff * x_diff + y_diff * y_diff);
18 }
19 
20 int main()
21 {
22 #ifdef LOCAL
23     freopen("in", "r", stdin);
24 #endif
25     int n, kase = 0;
26     char name[30];
27     while (scanf("%d", &n) && n)
28     {
29         n *= 2;
30         for (int i = 0; i < n; i++)
31             scanf("%s%d%d", name, &point[i].x, &point[i].y);
32         dp[0] = 0;
33         for (int s = 1; s < (1<<n); s++)
34         {
35             dp[s] = DBL_MAX;
36             int p = 0;
37             for ( ; p < n; p++)
38                 if (s & (1<<p))  break;
39             for (int i = p+1; i < n; i++)
40                 if (s & (1<<i))
41                     dp[s] = min(dp[s], dis(p, i)+dp[s^(1<<p)^(1<<i)]);
42         }
43         printf("Case %d: %.2lf\n", ++kase, dp[(1<<n)-1]);
44     }
45     return 0;
46 }
View Code

 

posted @ 2013-09-10 21:28  xiaobaibuhei  阅读(180)  评论(0编辑  收藏  举报