POJ 1873 The Fortified Forest (凸包,状态压缩枚举)
来源:互联网 发布:淘宝内裤真人秀在哪看 编辑:程序博客网 时间:2024/06/09 14:19
题目链接:http://poj.org/problem?id=1873
题意:给出一些树,每棵树有坐标,高度,以及价值,要求砍掉一些树,用那些木材,将其它树围起来,要求花最小的代价,代价相同,要求砍掉最少的树。
最后输出要砍掉哪几棵树和最后剩下多少长度的木材。
输入:
6
0 0 8 3
1 4 3 2
2 1 7 1
4 1 2 3
3 5 4 6
2 3 9 8
3
3 0 10 2
5 5 20 25
7 -3 30 32
0
n棵树,每行一棵,坐标,价值,高度。
因为树的棵数不多,所以可以直接状态压缩枚举来做,枚举时要注意判断砍0棵树的情况。
2^15次方,然后对剩下的树求一次凸包,求出凸包周长,判断木材是否够用,记录最优解。
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>#include <cmath>using namespace std;const double eps = 1e-8;const double PI = acos(-1.0);int sgn(double x) {if(fabs(x) < eps)return 0;if(x < 0)return -1; else return 1; }struct Point { double x,y, v, l;Point(){} Point(double _x,double _y) { x = _x;y = _y; } Point operator -(const Point &b)const { return Point(x - b.x,y - b.y); } double operator ^(const Point &b)const { return x*b.y - y*b.x; } double operator *(const Point &b)const { return x*b.x + y*b.y; } void transXY(double B) { double tx = x,ty = y; x = tx*cos(B) - ty*sin(B); y = tx*sin(B) + ty*cos(B); } };struct Line { Point s,e; Line(){} Line(Point _s,Point _e) { s = _s;e = _e; } pair<int,Point> operator &(const Line &b)const {Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0) {if(sgn((s-b.e)^(b.s-b.e)) == 0) return make_pair(0,res); else return make_pair(1,res); } double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t; res.y += (e.y-s.y)*t; return make_pair(2,res); } };double dist(Point a,Point b) { return sqrt((a-b)*(a-b)); }const int MAXN = 1010; Point list[MAXN]; int Stack[MAXN], top;bool _cmp(Point p1,Point p2) { double tmp = (p1-list[0])^(p2-list[0]); if(sgn(tmp) > 0)return true; else if(sgn(tmp) == 0 && sgn(dist(p1,list[0]) - dist(p2,list[0])) <= 0) return true; else return false; }void Graham(int n) {Point p0;int k = 0;p0 = list[0]; for(int i = 1;i < n;i++) { if( (p0.y > list[i].y) || (p0.y == list[i].y && p0.x > list[i].x) ) { p0 = list[i]; k = i; } } swap(list[k],list[0]); sort(list+1,list+n,_cmp); if(n == 1) {top = 1;Stack[0] = 0;return;}if(n == 2) { top = 2; Stack[0] = 0; Stack[1] = 1; return ; } Stack[0] = 0; Stack[1] = 1; top = 2; for(int i = 2;i < n;i++) { while(top > 1 && sgn((list[Stack[top-1]]-list[Stack[top-2]])^(list[i]-list[Stack[top-2]])) <= 0)top--; Stack[top++] = i; } } Point tree[20];int main() {int n;int kase = 1; while(~scanf("%d", &n), n) { printf("Forest %d\n", kase++); int i, j; for(i = 0; i < n; i++) { scanf("%lf %lf %lf %lf", &tree[i].x, &tree[i].y, &tree[i].v, &tree[i].l); } double ansc = 10000000, ansl;int anst[20];int num = 0; for(i = 0; i < 1 << n; i++) { int cnt = 0; double len1 = 0, len2 = 0, cost = 0; for(j = 0; j < n; j++) { if(i >> j & 1) { list[cnt++] = tree[j]; } else { len2 += tree[j].l; cost += tree[j].v; } } if(cnt == 0) continue; //砍0棵树 Graham(cnt); for(j = 0; j < top; j++) { len1 += dist(list[Stack[j]], list[Stack[(j + 1) % top]]); } if(len1 <= len2) { if(ansc > cost) { ansc = cost; ansl = len2 - len1; num = 0; for(j = 0; j < n; j++) { if(!(i >> j & 1)) { anst[num++] = j; } } } else if(ansc == cost){ if(n - cnt < num) { ansc = cost; ansl = len2 - len1; num = 0; for(j = 0; j < n; j++) { if(i >> j & 1) { anst[num++] = j; } } } } } } printf("Cut these trees:"); for(i = 0; i < num; i++) { printf(" %d", anst[i] + 1); } printf("\n"); printf("Extra wood: "); printf("%.2lf\n\n", ansl); }return 0;}
0 0
- 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(凸包+DFS枚举)
- 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(凸包+枚举)
- poj 1873The Fortified Forest (凸包 二进制枚举)
- POJ 1873 The Fortified Forest (状态压缩+凸包 WF 推荐)
- poj 1873 The Fortified Forest(凸包)
- poj 1873 The Fortified Forest(枚举+凸包边长计算)
- POJ 1873 The Fortified Forest 二进制枚举 + 凸包 (final水题)
- POJ 1873 The Fortified Forest(凸包+枚举 World Finals 1999啊)
- SQL中CASE WHEN使用实例
- nginx File not found!
- [Bugfix]Error opening new searcher. exceeded limit of maxWarmingSearchers=2, try again later.
- 提取出来的工具类
- java project 发布成为可运行文件exe
- POJ 1873 The Fortified Forest (凸包,状态压缩枚举)
- android 将手机号中间隐藏为星号(*)
- 1
- Linux命令 --- 文件比较diff/cmp
- 代码笔记 | 填写验证码倒计时60秒
- swift学习笔记 --- Control Flow
- 关于tomcat启动闪退的问题,以及使用tomcat域名绑定的问题
- 机器学习如何帮助Caesars大涨邮件绩效
- 安卓模拟器Genymotion安装使用教程详解