UVA 811 - The Fortified Forest(凸包)
2014-06-27 16:08
351 查看
题目:The Fortified Forest
题意:二维平面上有n棵树,每棵树用一个点(x,y)表示,同时还有树自身的价值v以及用这棵树造栅栏的长度l。
现在要用其中一些树来当材料建造栅栏将剩下的树围起来,要求当材料的树的价值应该最小,如果多种情况符合,则取个数最少那个。
要求输出用作材料的树的编号以及造完栅栏后剩下的材料长度。
因为n<=15,所以可以直接枚举要砍的树,计算出砍下的树的总长度len,然后对剩下的点求凸包,计算凸包的周长used,如果len>=used说明当前方案可行,根据题目要求进行选择即可。
题意:二维平面上有n棵树,每棵树用一个点(x,y)表示,同时还有树自身的价值v以及用这棵树造栅栏的长度l。
现在要用其中一些树来当材料建造栅栏将剩下的树围起来,要求当材料的树的价值应该最小,如果多种情况符合,则取个数最少那个。
要求输出用作材料的树的编号以及造完栅栏后剩下的材料长度。
因为n<=15,所以可以直接枚举要砍的树,计算出砍下的树的总长度len,然后对剩下的点求凸包,计算凸包的周长used,如果len>=used说明当前方案可行,根据题目要求进行选择即可。
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<cmath> using namespace std; const int inf = 0x7fffffff; const double eps = 1e-8; struct Point{ double x, y; Point(){} Point(double x, double y):x(x),y(y){} bool operator < (const Point &tmp)const{ return x<tmp.x || (fabs(x-tmp.x)<eps&&y<tmp.y); } Point operator + (Point A){ return Point(x+A.x, y+A.y); } Point operator - (Point A){ return Point(x-A.x, y-A.y); } }; double dis(Point &A, Point &B){ return sqrt((A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y)); } double det(Point A, Point B){ return A.x*B.y - A.y*B.x; } int n, v[20], l[20]; Point p[20]; vector<Point> V; Point ch[20]; double ex, used; double ConvexHull(){//返回凸包周长 int m = 0; sort(V.begin(), V.end()); for(int i=0; i<V.size(); i++){ while(m>1 && det(ch[m-1]-ch[m-2], V[i]-ch[m-2])<=0) m--; ch[m++] = V[i]; } int k = m; for(int i=V.size()-2; i>=0; i--){ while(m>k && det(ch[m-1]-ch[m-2], V[i]-ch[m-2])<=0) m--; ch[m++] = V[i]; } double res = 0; for(int i=0; i<m-1; i++){ res += dis(ch[i], ch[i+1]); } return res; } int main(){ int ct = 0; while(~scanf("%d", &n) && n){ if(ct) puts(""); for(int i=0; i<n; i++){ scanf("%lf %lf", &p[i].x, &p[i].y); scanf("%d %d", v+i, l+i); } int ans=inf, st, cnt, tmp, len; for(int i=1; i<(1<<n); i++){ V.clear(); tmp = 0; len = 0; for(int j=0; j<n; j++){ if(i&(1<<j)){ tmp += v[j]; len += l[j]; } else{ V.push_back(p[j]); } } //这里做个剪枝,如果当前方案就算可行也不比当前优的话,则忽略。 if(tmp>ans || (tmp==ans && (n-V.size())>=cnt)) continue; used = ConvexHull(); if(len>=used){ ans = tmp; cnt = n-V.size(); st = i; ex = len - used; } } printf("Forest %d\n", ++ct); printf("Cut these trees:"); for(int j=0; j<n; j++){ if(st&(1<<j)) printf(" %d", j+1); } puts(""); printf("Extra wood: %.2lf\n", ex); } return 0; }
相关文章推荐
- (beginer) 凸包+枚举 UVA 811 - The Fortified Forest
- uva 811 - The Fortified Forest(暴力+凸包)
- UVa 811 - The Fortified Forest
- The Fortified Forest(poj1873位运算枚举+凸包)
- [POJ1873]The Fortified Forest(dfs+计算几何-凸包)
- POJ 1873 The Fortified Forest 二进制枚举 + 凸包 (final水题)
- POJ 1873 The Fortified Forest (凸包,状态压缩枚举)
- poj 1873 The Fortified Forest(凸包)
- POJ 1873 The Fortified Forest [凸包 枚举]
- poj1873 The Fortified Forest 凸包+枚举 水题
- poj 1873 The Fortified Forest (凸包)
- POJ 1873 The Fortified Forest 暴力凸包
- 简单几何(凸包+枚举) POJ 1873 The Fortified Forest
- POJ 1873 The Fortified Forest(凸包+状态枚举)
- poj 1873 The Fortified Forest 搜索+凸包
- POJ 1873 The Fortified Forest(凸包+枚举)
- poj 1873 The Fortified Forest 凸包+位运算枚举 world final 水题
- The Fortified Forest - POJ 1873(状态枚举+求凸包周长)
- POJ 1873 The Fortified Forest 暴力凸包
- POJ 1873 The Fortified Forest (状态压缩+凸包 WF 推荐)