POJ 1873 The Fortified Forest 凸包 二进制枚举
n最大15,二进制枚举不会超时。枚举不被砍掉的树,然后求凸包
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include <cstring>
#define eps 1e-8
#define INF 1e9
using namespace std; const int MAXN = 20; struct Point
{
int x,y;
int v,l;
}; Point pot[MAXN];
int stck[MAXN],top; int sgn(double x)
{
if(fabs(x) < eps) return 0;
return x < 0 ? -1:1;
} int cross(Point p0,Point p1,Point p2) //计算叉积 p0p1 X p0p2
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
} double dis(Point p1,Point p2) //计算 p1p2的 距离
{
return sqrt((double)(p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));
} bool cmp(Point p1,Point p2) //极角排序函数,角度相同则距离小的在前面
{
int tmp=cross(pot[0],p1,p2);
if(tmp>0) return true;
else if(tmp==0&&dis(pot[0],p1)<dis(pot[0],p2)) return true;
else return false;
} void init(int n) //输入,并把最左下方的点放在 pot[0]。并且进行极角排序
{
int i,k;
Point p0;
p0 = pot[0];
k=0;
for(i=1; i<n; i++)
{
if( (p0.y>pot[i].y) || ((p0.y==pot[i].y)&&(p0.x>pot[i].x)) )
{
p0 = pot[i];
k=i;
}
}
pot[k]=pot[0];
pot[0]=p0;
sort(pot+1,pot+n,cmp);
} void graham(int n)
{
int i;
if(n==1)
{
top=0;
stck[0]=0;
}
if(n==2)
{
top=1;
stck[0]=0;
stck[1]=1;
}
if(n>2)
{
for(i=0; i<=1; i++) stck[i]=i;
top=1; for(i=2; i<n; i++)
{
while(top>0&&cross(pot[stck[top-1]],pot[stck[top]],pot[i])<=0) top--;
top++;
stck[top]=i;
}
}
} Point p[MAXN]; int main()
{
// freopen("in.txt","r",stdin);
int n, val, len, minv, maxn, ans;
double exc;
int Case = 0;
while(~scanf("%d", &n) && n)
{
val = len = 0;
for(int i=0; i<n; i++)
{
scanf("%d%d%d%d", &p[i].x, &p[i].y, &p[i].v, &p[i].l);
val += p[i].v;
len += p[i].l;
}
minv = INF;
maxn = 0;
for(int i=1; i< (1<<n)-1; i++)
{
int cnt, tmp ,v ,l;
cnt = 0;
tmp = i;
v = val;
l = len;
for(int j=0; j<n; j++)
{
if(tmp&1)
{
pot[cnt++] = p[j];
v -= p[j].v;
l -= p[j].l;
}
tmp >>= 1;
}
init(cnt);
graham(cnt);
double d = 0;
for(int j=0; j<=top; j++)
d += dis(pot[stck[j]], pot[stck[(j+1)%(top+1)]]);
if(sgn(l - d) >= 0)
{
if(v < minv || (v == minv && cnt > maxn))
{
minv = v;
maxn = cnt;
ans = i;
exc = l - d;
}
}
}
printf("Forest %d\nCut these trees: ", ++Case);
for(int i=0; i<n; i++)
{
if((ans&1) == 0) printf("%d ", i+1);
ans >>= 1;
}
printf("\nExtra wood: %.2lf\n\n", exc);
}
return 0;
}
POJ 1873 The Fortified Forest 凸包 二进制枚举的更多相关文章
- POJ 1873 The Fortified Forest [凸包 枚举]
		
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6400 Accepted: 1 ...
 - POJ 1873 - The Fortified Forest 凸包 + 搜索 模板
		
通过这道题发现了原来写凸包的一些不注意之处和一些错误..有些错误很要命.. 这题 N = 15 1 << 15 = 32768 直接枚举完全可行 卡在异常情况判断上很久,只有 顶点数 &g ...
 - POJ 1873 The Fortified Forest(枚举+凸包)
		
Description Once upon a time, in a faraway land, there lived a king. This king owned a small collect ...
 - 简单几何(凸包+枚举) POJ 1873 The Fortified Forest
		
题目传送门 题意:砍掉一些树,用它们做成篱笆把剩余的树围起来,问最小价值 分析:数据量不大,考虑状态压缩暴力枚举,求凸包以及计算凸包长度.虽说是水题,毕竟是final,自己状压的最大情况写错了,而且忘 ...
 - POJ 1873 The Fortified Forest(凸包)题解
		
题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少 思路:n<=15,那么直接遍历2^15,判断每种情况.这里要优化一下 ...
 - ●POJ 1873 The Fortified Forest
		
题链: http://poj.org/problem?id=1873 题解: 计算几何,凸包 枚举被砍的树的集合.求出剩下点的凸包.然后判断即可. 代码: #include<cmath> ...
 - POJ 1873 The Fortified Forest
		
题意:是有n棵树,每棵的坐标,价值和长度已知,要砍掉若干根,用他们围住其他树,问损失价值最小的情况下又要长度足够围住其他树,砍掉哪些树.. 思路:先求要砍掉的哪些树,在求剩下的树求凸包,在判是否可行. ...
 - poj1873 The Fortified Forest 凸包+枚举 水题
		
/* poj1873 The Fortified Forest 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...
 - 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 ...
 
随机推荐
- Ansible playbook编写Apache角色
			
编写Apache角色:使用源码安装 在files中下载扩展包和安装包 [root@localhost project]# ls roles/httpd/files/ apr-1.6.5.tar.gz ...
 - 第七章 DevOps工具链
			
DevOps工具生态圈 协同开发工具 敏捷开发 可视化 加强团队沟通协作 数据分析 协同开发 持续集成工具 Jenkins 自动化编译 自动化测试 自动化部署 丰富的插件库 版本管理工具 Git 简介 ...
 - 『动善时』JMeter基础 — 27、通过JMeter函数助手实现参数化
			
目录 1.测试计划中的元件 2.数据文件内容 3.函数助手配置 (1)函数助手的打开方式 (2)函数助手界面介绍 (3)编辑后的函数助手界面 4.HTTP请求组件内容 5.线程组元件内容 6.脚本运行 ...
 - Qt 进度条
			
一.前言 有时我们需要在表格(QTableWidget).树状栏(QTreeWidget)中直观显示任务进度或消耗百分比,达到报表显示的形式,可通过重写QLabel的方式实现. 1.进度条控件功能 1 ...
 - 重新整理 .net core 实践篇—————配置系统之间谍[八](文件监控)
			
前言 前文提及到了当我们的配置文件修改了,那么从 configurationRoot 在此读取会读取到新的数据,本文进行扩展,并从源码方面简单介绍一下,下面内容和前面几节息息相关. 正文 先看一下,如 ...
 - 上传靶机实战之upload-labs解题
			
前言 我们知道对靶机的渗透可以提高自己对知识的掌握能力,这篇文章就对上传靶机upload-labs做一个全面的思路分析,一共21个关卡.让我们开始吧,之前也写过关于上传的专题,分别为浅谈文件上传漏洞( ...
 - 查询rman备份信息常用指令
			
查询rman备份信息常用指令 ----登陆到rman $rman target / ----以精简的格式查看备份信息 RMAN> list backup of database summar ...
 - BeetleX之Vue ElementUI生成工具
			
BeetleX.WebFamily在新版本的功能中引入了一个全新的功能,通过这一功能可以大大节省UI的开发工作量.组件集成了一个图形化的UI编辑器,可以连接数据库对数据表或查询快速度生成编辑和数据查询 ...
 - list 分批导入db, 每1000条数据一批 ,  从字符串中获取数字,小数, 版本号比较
			
//这个有个弊端: 分组后分批导入, 是阻塞的,我没有导入完成,别人就不能导入, 这里可以优化成异步,线程池 public static void main(String[] args) { Rand ...
 - 数据结构-几种Tree
			
1.二叉查找树 或 二叉排序树 (BST) 性质:左子树的键值小于根的键值,右子树的键值大于根的键值. 2.平衡二叉树(AVL Tree) 它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且 ...