poj1873

题意:给定一些树木的坐标及砍掉树木所能围成的长度,还有他的价值,问在损失最少的价值的情况下砍掉那些树,使得砍掉的树足够围住剩下的树。。

思路:枚举砍掉的树,然后进行一次凸包,判断即可

code:

  

  1 /*
  2   State: Accepted
  3   Time:  2013-03-30 17:27:14
  4 */
  5 
  6 #include <iostream>
  7 #include <cmath>
  8 #include <cstring>
  9 #include <cstdlib>
 10 #include <cmath>
 11 #include <algorithm>
 12 #include <cstdio>
 13 #include <set>
 14 #define M0 memset(a, 0 ,sizeof(a))
 15 struct oo {int x ,y , l, v;};
 16 using namespace std;
 17 oo a[100], b[100], q[100];
 18 int n ,  tot, ansv , ansopt , px , py , test = 0,ansnum;
 19 double anslen;
 20 void init(){
 21    anslen = 0;
 22    ansv = ansopt = 0;
 23    ansnum = 0x7fffffff;
 24    memset(a, 0 ,sizeof(a));
 25    for (int i = 1;  i <= n; ++i)
 26       scanf("%d%d%d%d",&a[i].x, &a[i].y, &a[i].v ,&a[i].l); 
 27      
 28 }
 29 
 30 bool cmp(const oo a, const oo b){
 31      if (a.x  < b.x|| a.x == b.y && a.y < b.y ) return true;
 32      return false;
 33 }
 34      
 35 bool cmpx(const oo a, const oo b){
 36      int x1 = a.x - px;
 37      int x2 = b.x - px;
 38      int y1 = a.y - py;
 39      int y2 = b.y - py;
 40      if (x1 * y2 -x2* y1 > 0) return true;
 41      if (x1*y2 - x2*y1 == 0 && x1*x1 + y1*y1 < x2*x2 +y2*y2) return true;
 42      return false;
 43 }
 44 
 45 void solve(int opt){
 46      tot = 0;
 47      oo c;
 48      memset(b, 0, sizeof(b));
 49      int value = 0 , len = 0;
 50      int x1 , y1, x2, y2;
 51      double x,y;
 52      for (int i = 1;  i <= n; ++i){
 53          if  (((1 << i) & opt )!= 0){
 54               b[++tot] = a[i];
 55               value += a[i].v;  
 56          }
 57         else  len += a[i].l;
 58      }
 59      if (value < ansv) return;
 60      sort(b+1, b+1+tot, cmp);
 61     for (int i = 2; i < tot; ++i)
 62        for (int j = i + 1; j <= tot;  ++j )
 63          if (!cmpx(a[i], a[j])) {
 64               c = a[i];
 65               a[i] = a[j];
 66               a[j] = c;
 67          }
 68     // if (tot > 2) sort(b + 2, b + tot + 1, cmpx);
 69      memset(q, 0 ,sizeof(q));
 70      q[1] = b[1];
 71      q[2] = b[2];
 72      int h = 1 , t = 2;
 73      for (int i = 3;  i <= tot; ++i){
 74           while (t > h){
 75                x1 = b[i].x - q[t-1].x;
 76                x2 = q[t].x - q[t-1].x;
 77                y1 = b[i].y - q[t-1].y;
 78                y2 = q[t].y - q[t-1].y;
 79                if (x1*y2-x2*y1 > 0) -- t;
 80                else break;
 81           }
 82           q[++t] = b[i];
 83      }
 84       if (tot == 1) t = 1;
 85      q[++t] = b[1];
 86      double len1 = 0;
 87      for (int i = 2; i <= t; ++i){
 88          x = q[i].x - q[i-1].x;
 89          y = q[i].y - q[i-1].y;
 90          len1 += (pow(x*x+y*y,0.5));
 91      }
 92      
 93      if (len >= len1){
 94           if (ansv < value || ansv == value && ansnum > n - tot){   
 95               ansv = value;
 96               ansopt = opt;   
 97               anslen = len - len1;
 98               ansnum = n - tot;
 99           }
100      }
101 }
102 
103 void dfs(int i, int opt){
104     if (i > n) {
105        solve(opt); 
106        return;
107     }
108     dfs(i + 1, opt);
109     dfs(i + 1, opt |(1 << i) );
110 
111 }
112 
113 void print(){
114     printf("Forest %d\nCut these trees: ",test);
115     for (int i =1; i <= n; ++i)
116     if (((1 << i)&ansopt) == 0)
117         printf("%d ",i);
118     printf("\nExtra wood: %.2lf\n\n",anslen);
119         
120 }
121 
122 int main(){
123     freopen("poj1873.in","r",stdin);
124     freopen("poj1873.out","w",stdout);
125     while ( scanf("%d",&n) != EOF && n != 0)
126     {
127         ++test;
128         init();
129         dfs(1, 0);
130         print();
131     }   
132     fclose(stdin); fclose(stdout);
133 }
原文地址:https://www.cnblogs.com/yzcstc/p/3015720.html