[SCOI2004]森林-枚举 凸包

15个可能是阶乘、2n次方、枚举、乘大系数、状压

我犯的错误:

清多组 

1个点凸包特判 否则80

View Code
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <algorithm>
 5 using namespace std;
 6 const int N = 1000;
 7 int n, x[N], y[N], w[N], l[N], W, top, c, t1 = 0x3f3f3f3f, cho, t3;
 8 double t2, r, L;
 9 bool v[N];
10 struct Q {
11     int x, y;
12 }p[N], stk[N];
13 inline bool cmp (const Q & a, const Q & b)
14 {
15     return a.y == b.y ? a.x < b.x : a.y < b.y;
16 }
17 inline int t (const Q & a, const Q & b, const Q & c)
18 {
19     int x1 = b.x - a.x, y1 = b.y - a.y;
20     int x2 = c.x - b.x, y2 = c.y - b.y;
21     return x1 * y2 - x2 * y1;
22 }
23 inline double d (const Q & a, const Q & b)
24 {
25     return sqrt ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
26 }
27 inline double ck ()
28 {
29     c = 0;
30     for (int i = 1; i <= n; i ++)
31         if (!v[i])
32             p[++ c].x = x[i], p[c].y = y[i];
33     sort (p + 1, p + 1 + c, cmp);
34     top = 0;
35     stk[++ top] = p[1];
36     stk[++ top] = p[2];
37     for (int i = 3; i <= c; i ++)
38     {
39         while (top > 1 && t (stk[top - 1], stk[top], p[i]) < 0) top --;
40         stk[++ top] = p[i];
41     }
42     int base = top;
43     stk[++ top] = p[c - 1];
44     for (int i = c - 2; i >= 1; i --)
45     {
46         while (top > base && t (stk[top - 1], stk[top], p[i]) < 0) top --;
47         stk[++ top] = p[i];
48     }
49     double z (0);
50     if (c == 1) top = 1;
51     for (int i = 2; i <= top; i ++)
52         z += d (stk[i], stk[i - 1]);
53     return z;
54 }
55 inline int calc (int x)
56 {
57     int c (0);
58     for (int i = 0; i < n; i ++)
59         if (x >> i & 1)
60             c ++;
61     return c;
62 }
63 inline void M (int x)
64 {
65     memset (v, 0, sizeof v);
66     W = 0, L = 0;
67     for (int i = 0; i < n; i ++)
68         if (x >> i & 1)
69             v[i + 1] = true, W += w[i + 1], L += l[i + 1];
70     r = ck ();
71     if (r < L && W < t1)
72         t1 = W, t2 = L - r, t3 = calc (x), cho = x;
73     if (r < L && W == t1)
74         if (calc (x) < t3)
75             t1 = W, t2 = L - r, t3 = calc (x), cho = x;
76 }
77 int main ()
78 {
79     scanf ("%d", &n);
80     for (int i = 1; i <= n; i ++)
81         scanf ("%d%d%d%d", &x[i], &y[i], &w[i], &l[i]);
82     for (int i = 0; i < (1 << n) - 1; i ++)
83         M (i);
84     printf ("%.2lf\n", t2);
85     for (int i = 0; i < n; i ++)
86         if ((cho >> i) & 1)
87             printf ("%d ", i + 1);
88     return 0;
89 }
posted @ 2012-11-22 00:30  Moretimes  阅读(209)  评论(0编辑  收藏  举报