The Fortified Forest
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 6198   Accepted: 1744

Description

Once upon a time, in a faraway land, there lived a king. This king owned a small collection of rare and valuable trees, which had been gathered by his ancestors on their travels. To protect his trees from thieves, the king ordered that a high fence be built around them. His wizard was put in charge of the operation. 
Alas, the wizard quickly noticed that the only suitable material available to build the fence was the wood from the trees themselves. In other words, it was necessary to cut down some trees in order to build a fence around the remaining trees. Of course, to prevent his head from being chopped off, the wizard wanted to minimize the value of the trees that had to be cut. The wizard went to his tower and stayed there until he had found the best possible solution to the problem. The fence was then built and everyone lived happily ever after.

You are to write a program that solves the problem the wizard faced.

Input

The input contains several test cases, each of which describes a hypothetical forest. Each test case begins with a line containing a single integer n, 2 <= n <= 15, the number of trees in the forest. The trees are identified by consecutive integers 1 to n. Each of the subsequent n lines contains 4 integers xi, yi, vi, li that describe a single tree. (xi, yi) is the position of the tree in the plane, vi is its value, and li is the length of fence that can be built using the wood of the tree. vi and li are between 0 and 10,000. 
The input ends with an empty test case (n = 0). 

Output

For each test case, compute a subset of the trees such that, using the wood from that subset, the remaining trees can be enclosed in a single fence. Find the subset with minimum value. If more than one such minimum-value subset exists, choose one with the smallest number of trees. For simplicity, regard the trees as having zero diameter. 
Display, as shown below, the test case numbers (1, 2, ...), the identity of each tree to be cut, and the length of the excess fencing (accurate to two fractional digits).

Display a blank line between test cases.

Sample Input

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

Sample Output

Forest 1
Cut these trees: 2 4 5
Extra wood: 3.16 Forest 2
Cut these trees: 2
Extra wood: 15.00
/*
poj 1873 凸包+枚举 给你n棵树,已知树的树的长度以及他们的价值。要砍掉一些树来给剩下的数围一个篱笆
要求剩下的数价值尽可能大,如果价值相同则希望剩下的树尽可能多 因为最多15棵,枚举需要砍掉的树,然后通过凸包判断是否能围成,记录一下即可 hhh-2016-05-07 21:27:41
*/
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#include <cstdio>
#include <queue>
#include <cmath>
#include <algorithm>
#include <functional>
#include <map>
using namespace std;
#define lson (i<<1)
#define rson ((i<<1)|1)
typedef long long ll;
using namespace std;
const int maxn = 20;
double PI = 3.1415926;
double eps = 1e-8; int sgn(double x)
{
if(fabs(x) < eps) return 0;
if(x < 0)
return -1;
else
return 1;
} struct Point
{
double x,y;
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;
}
}; struct Line
{
Point s,t;
Line() {}
Line(Point _s,Point _t)
{
s = _s;
t = _t;
}
pair<int,Point> operator &(const Line&b)const
{
Point res = s;
if( sgn((s-t) ^ (b.s-b.t)) == 0) //通过叉积判断
{
if( sgn((s-b.t) ^ (b.s-b.t)) == 0)
return make_pair(0,res);
else
return make_pair(1,res);
}
double ta = ((s-b.s)^(b.s-b.t))/((s-t)^(b.s-b.t));
res.x += (t.x-s.x)*ta;
res.y += (t.y-s.y)*ta;
return make_pair(2,res);
}
};
Point lis[maxn];
int Stack[maxn],top; double dist(Point a,Point b)
{
return sqrt((a-b)*(a-b));
}
Point ta[20];
bool cmp(Point a,Point b)
{
double t = (a-ta[0])^(b-ta[0]);
if(sgn(t) == 0)
{
return dist(a,ta[0]) <= dist(b,ta[0]);
}
if(sgn(t) < 0)
return false;
else
return true;
} int tot;
double Graham(int n)
{
Point p;
if(n == 1 || n == 0)
{
return 0;
}
if(n == 2)
{
return dist(ta[0],ta[1])*2;
}
int k = 0;
p = ta[0];
for(int i = 1; i < n; i++)
{
if(p.y > ta[i].y || (p.y == ta[i].y && p.x > ta[i].x))
p = ta[i],k = i;
}
swap(ta[0],ta[k]);
sort(ta+1,ta+n,cmp);
Stack[0] = 0;
Stack[1] = 1;
top = 2;
for(int i = 2; i < n; i++)
{
while(top > 1 && sgn((ta[Stack[top-1]]-ta[Stack[top-2]])
^ (ta[i]-ta[Stack[top-2]])) <= 0)
top --;
Stack[top++] = i;
}
double len = 0;
for(int i = 0; i < top; i++)
{
if(i == top - 1)
len += dist(ta[Stack[i]],ta[Stack[0]]);
else
len += dist(ta[Stack[i]],ta[Stack[i+1]]);
}
return len;
} int val[maxn];
double lent[maxn]; int main()
{
//freopen("in.txt","r",stdin);
int n;
int cas = 1;
while(scanf("%d",&n) && n)
{
if(cas != 1)
printf("\n");
for(int i = 0; i < n; i++)
{
scanf("%lf%lf%d%lf",&lis[i].x,&lis[i].y,&val[i],&lent[i]);
}
int ansV = 0x7fffffff,ansN = 0x7fffffff,ansX = 0;
double ansL = 0;
for(int i = 0; i < (1<<n); i++)
{
tot = 0;
double lans = 0;
int vans = 0;
for(int j = 0; j < n; j++)
{
if(i & (1 << j))
{
vans += val[j];
lans += lent[j];
}
else
{
ta[tot++] = lis[j];
}
}
if(vans > ansV)
continue;
double t = Graham(tot);
if(lans >= t)
{
if(vans < ansV || (n-tot < ansN && vans == ansV))
{
ansV = vans;
ansL = lans-t;
ansX = i;
ansN = n-tot;
}
}
}
printf("Forest %d\n",cas++);
printf("Cut these trees:");
for(int i = 0; i < n; i++)
{
if(ansX&(1 << i))
printf(" %d",i+1);
}
printf("\n");
printf("Extra wood: %.2f\n",ansL);
}
return 0;
}

  

poj 1873 凸包+枚举的更多相关文章

  1. poj 1873(枚举所有的状态+凸包)

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6115   Accepted: 1 ...

  2. The Fortified Forest - POJ 1873(状态枚举+求凸包周长)

    题目大意:有个国王他有一片森林,现在他想从这个森林里面砍伐一些树木做成篱笆把剩下的树木围起来,已知每个树都有不同的价值还有高度,求出来砍掉那些树可以做成篱笆把剩余的树都围起来,要使砍伐的树木的价值最小 ...

  3. ●POJ 1873 The Fortified Forest

    题链: http://poj.org/problem?id=1873 题解: 计算几何,凸包 枚举被砍的树的集合.求出剩下点的凸包.然后判断即可. 代码: #include<cmath> ...

  4. poj1873 The Fortified Forest 凸包+枚举 水题

    /* poj1873 The Fortified Forest 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...

  5. poj 1113 凸包周长

    Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 33888   Accepted: 11544 Descriptio ...

  6. Poj 2187 凸包模板求解

    Poj 2187 凸包模板求解 传送门 由于整个点数是50000,而求凸包后的点也不会很多,因此直接套凸包之后两重循环即可求解 #include <queue> #include < ...

  7. 简单几何(凸包+枚举) POJ 1873 The Fortified Forest

    题目传送门 题意:砍掉一些树,用它们做成篱笆把剩余的树围起来,问最小价值 分析:数据量不大,考虑状态压缩暴力枚举,求凸包以及计算凸包长度.虽说是水题,毕竟是final,自己状压的最大情况写错了,而且忘 ...

  8. POJ 1873 The Fortified Forest [凸包 枚举]

    The Fortified Forest Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 6400   Accepted: 1 ...

  9. POJ 1873 The Fortified Forest(枚举+凸包)

    Description Once upon a time, in a faraway land, there lived a king. This king owned a small collect ...

随机推荐

  1. verilog学习笔记(2)_一个小module及其tb

    module-ex_cnt module ex_cnt( input wire sclk, input wire rst_n, output wire[9:0] cnt ); reg [9:0] cn ...

  2. bzoj千题计划252:bzoj1095: [ZJOI2007]Hide 捉迷藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1095 点分树+堆 请去看 http://www.cnblogs.com/TheRoadToTheGo ...

  3. 学大伟业 国庆Day2

    期望得分:30+100+0=130 实际得分:30+100+20=150 忍者钩爪 (ninja.pas/c/cpp) [问题描述] 小Q是一名酷爱钩爪的忍者,最喜欢飞檐走壁的感觉,有一天小Q发现一个 ...

  4. AWK读书笔记

    1.awk 'parttern {action}' filename 从文件中逐行读取并匹配parttern,若匹配成功执行action否则读取下一行. parttern和action都可选,若省略p ...

  5. 从PRISM开始学WPF(三)Prism-Region?

    从PRISM开始学WPF(一)WPF? 从PRISM开始学WPF(二)Prism? 从PRISM开始学WPF(三)Prism-Region? 从PRISM开始学WPF(四)Prism-Module? ...

  6. Python内置函数(33)——any

    英文文档: any(iterable) Return True if any element of the iterable is true. If the iterable is empty, re ...

  7. Python内置函数(18)——bin

    英文文档: bin(x) Convert an integer number to a binary string. The result is a valid Python expression. ...

  8. Python入门之函数的嵌套/名称空间/作用域/函数对象/闭包函数

    本篇目录: 一.函数嵌套 二.函数名称空间与作用域 三.函数对象 四.闭包函数 ============================================================ ...

  9. Struts(十八):通过CURD来学习PrepareInterceptor拦截器

    PrepareInterceptor拦截器的用法: 1.若Action实现了Preparable接口,则Action方法需实现prepare()方法: 2.PrepareInterceptor拦截器S ...

  10. geotrellis使用(三十七)COG 基础介绍

    前言 Geotrellis 已经迭代到了 2.0 版本(截止写作此文时为 2.0.0-SNAPSHOT 版),2.0 版多了很多新的特性,其中最重要的应该就是 COG,COG 是什么鬼?刚看到时我也是 ...