[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 }