poj 1873(枚举所有的状态+凸包)
| Time Limit: 1000MS | Memory Limit: 30000K | |
| Total Submissions: 6115 | Accepted: 1720 |
Description
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
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
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
题意:国王有一些树,他想砍掉一些树做篱笆围住剩下的树,每棵树都有坐标,价值和做成篱笆长度,我们应该使砍掉的树的价值尽可能的小并且做成的篱笆能够围住剩下的树,如果方案的价值相同选择砍掉数量
少的,最后输出砍掉的树的编号和篱笆围了之后还能剩下多少。
题解:深坑啊。。。WA了好多次,竟然是cmp函数里面的变量p[0]的函数名冲突了...world final的水题都好难。。过,但是想法不难。。就是每次枚举那些树不取和取,不超过2^15次方,用二进制表示..然后再进行凸包。。比较。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <algorithm>
#include <stdlib.h>
using namespace std;
const double eps = 1e-;
const int N = ;
struct Point
{
double x,y,value,len;
} p[N],q[N];
Point Stack[N];
int n;
double cross(Point a,Point b,Point c)
{
return (a.x-c.x)*(b.y-c.y)-(a.y-c.y)*(b.x-c.x);
}
double dis(Point a,Point b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
Point po; //大坑
int cmp(Point a,Point b)
{
if(cross(a,b,po)>) return ;
if(cross(a,b,po)==&&dis(b,po)-dis(a,po)>eps) return ;
return ;
}
double Graham(Point p[],int n)
{
if(n==||n==) return ;
if(n==) return *dis(p[],p[]);
int k =;
for(int i=; i<n; i++)
{
if(p[k].y>p[i].y||((p[k].y==p[i].y)&&(p[k].x>p[i].x))) k=i;
}
swap(p[],p[k]);
po = p[]; ///嗯,这里
int top=;
sort(p+,p+n,cmp);
Stack[]=p[];
Stack[]=p[];
Stack[]=p[];
for(int i=; i<n; i++)
{
while(top>=&&cross(p[i],Stack[top],Stack[top-])>=)
{
top--;
}
Stack[++top]=p[i];
}
double ans = ;
for(int i=; i<=top; i++)
{
ans+=dis(Stack[i],Stack[i-]);
}
ans+=dis(Stack[top],Stack[]);
return ans;
}
int main()
{
int _count = ;
while(scanf("%d",&n)!=EOF&&n)
{
for(int i=; i<n; i++)
{
scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].value,&p[i].len);
}
int t = (<<n)-;
int cnt[N],id[N];///保存要砍掉的树的编号
double save=;
int num=; ///要砍掉的数的数目
double mi=; ///保存要砍掉的树的最小价值
for(int i=; i<t; i++) ///1代表砍掉这棵树,0代表不砍,至少要砍一棵树
{
double value=,len=;
int k=,k1=;
for(int j=; j<n; j++)
{
if((i>>j)&) ///移位操作,表示当前第j+1棵树要砍掉
{
cnt[k++] = j;
value+=p[j].value;
len+=p[j].len;
}
else q[k1++] = p[j];
}
double L = Graham(q,k1);
if(len-L>eps) ///如果能够组成的篱笆长度大于凸包周长
{
if(mi-value>eps||(fabs(value-mi)<eps&&k<num))
{
mi = value;
for(int j=; j<k; j++) id[j]=cnt[j];
num = k;
save = len - L;
}
}
}
printf("Forest %d\nCut these trees: ",_count++);
for(int i=; i<num; i++)
{
printf("%d ",id[i]+);
}
printf("\nExtra wood: %.2lf\n\n",save);
}
return ;
}
poj 1873(枚举所有的状态+凸包)的更多相关文章
- POJ 1873 The Fortified Forest(凸包)题解
题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少 思路:n<=15,那么直接遍历2^15,判断每种情况.这里要优化一下 ...
- The Fortified Forest - POJ 1873(状态枚举+求凸包周长)
题目大意:有个国王他有一片森林,现在他想从这个森林里面砍伐一些树木做成篱笆把剩下的树木围起来,已知每个树都有不同的价值还有高度,求出来砍掉那些树可以做成篱笆把剩余的树都围起来,要使砍伐的树木的价值最小 ...
- poj 1873 凸包+枚举
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6198 Accepted: 1 ...
- ●POJ 1873 The Fortified Forest
题链: http://poj.org/problem?id=1873 题解: 计算几何,凸包 枚举被砍的树的集合.求出剩下点的凸包.然后判断即可. 代码: #include<cmath> ...
- poj - 3254 - Corn Fields (状态压缩)
poj - 3254 - Corn Fields (状态压缩)超详细 参考了 @外出散步 的博客,在此基础上增加了说明 题意: 农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以放牧的( ...
- POJ 1873 UVA 811 The Fortified Forest (凸包 + 状态压缩枚举)
题目链接:UVA 811 Description Once upon a time, in a faraway land, there lived a king. This king owned a ...
- 简单几何(凸包+枚举) POJ 1873 The Fortified Forest
题目传送门 题意:砍掉一些树,用它们做成篱笆把剩余的树围起来,问最小价值 分析:数据量不大,考虑状态压缩暴力枚举,求凸包以及计算凸包长度.虽说是水题,毕竟是final,自己状压的最大情况写错了,而且忘 ...
- POJ 1873 The Fortified Forest [凸包 枚举]
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6400 Accepted: 1 ...
- POJ 1873 The Fortified Forest(枚举+凸包)
Description Once upon a time, in a faraway land, there lived a king. This king owned a small collect ...
随机推荐
- Altium Designer多原理图、PCB更新处理
问题扫述: 一般一个同程有多个原理图.PCB.但是AD默认从原理图更新到PCB会把全部原理图都更新过去.因此需要稍加设置. 一.
- 3714: [PA2014]Kuglarz
3714: [PA2014]Kuglarz 链接 思路: 好题.对于每个点都需要确定它的值,那么一个点可以直接询问[i,i]来确定,或者已经知道了[i,j]和[i+1,j]推出来. 但是可能产生冲突, ...
- 接口&抽象类&继承&父类和子类
1.接口是什么? 接口可以理解为一个特殊的抽象类,是由全局常量和公共抽象方法组成的. 所以,如果,一个抽象类的方法都是抽象的,那么就可以通过接口的形式来表示. class 用于定义类 interfac ...
- DOS程序员手册(三)
56页 第4章DOS和BIOS接口 本章介绍了用户程序访问DOS内核和BIOS所提供的各种服务的方法.为了访问这 些服务,我们可以从任何编程语言中调用各个软件中断,这些中断便是我们在本 ...
- 一些优秀的SLAM博主
http://blog.csdn.net/u010566411 http://blog.csdn.net/qq_18661939/article/details/51782376 http://www ...
- python作业:HAproxy配置文件操作(第三周)
一.作业需求: 1. 根据用户输入输出对应的backend下的server信息 2. 可添加backend 和sever信息 3. 可修改backend 和sever信息 4. 可删除backend ...
- 虚函数&&虚继承
如果说没有虚函数的虚继承只是一个噩梦的话,那么这里就是真正的炼狱.这个C++中最复杂的继承层次在VS上的实现其实我没有完全理解,摸爬滚打了一番也算得出了微软的实现方法吧,至于一些刁钻的实现方式我也想不 ...
- jQuery静态分页功能
分页功能在做项目的过程中是常常用到的,下面是我常用的一款分页效果: 1.分页的CSS样式(page.css) #setpage { margin: 15px auto; text-align: cen ...
- foreach的理解
foreach的两种写法的解读 一.常见 1.理解:将数组元素逐个赋值给变量V,然后将v输出 2.代码: $arr = array(1,2,3,4,5); foreach($arr as $a){ e ...
- Codeforces Round #384 (Div. 2) 734E(二分答案+状态压缩DP)
题目大意 给定一个序列an,序列中只有1~8的8个整数,让你选出一个子序列,满足下列两个要求 1.不同整数出现的次数相差小于等于1 2.子序列中整数分布是连续的,即子序列的整数必须是1,1,1.... ...