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 凸包 二进制枚举的更多相关文章

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

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

  2. POJ 1873 - The Fortified Forest 凸包 + 搜索 模板

    通过这道题发现了原来写凸包的一些不注意之处和一些错误..有些错误很要命.. 这题 N = 15 1 << 15 = 32768 直接枚举完全可行 卡在异常情况判断上很久,只有 顶点数 &g ...

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

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

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

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

  5. POJ 1873 The Fortified Forest(凸包)题解

    题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少 思路:n<=15,那么直接遍历2^15,判断每种情况.这里要优化一下 ...

  6. ●POJ 1873 The Fortified Forest

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

  7. POJ 1873 The Fortified Forest

    题意:是有n棵树,每棵的坐标,价值和长度已知,要砍掉若干根,用他们围住其他树,问损失价值最小的情况下又要长度足够围住其他树,砍掉哪些树.. 思路:先求要砍掉的哪些树,在求剩下的树求凸包,在判是否可行. ...

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

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

  9. 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 ...

随机推荐

  1. python3.7[列表] 索引切片

    python3.7[列表] 索引  切片 排序     #### 列表.sort 永久排序   sorted(列表) 临时排序   ### >>> print(sorted(a))[ ...

  2. Java 语言的主要特性

    Java语言是简单的 Java语言的语法与C语言和C++语言很接近,使得大多数程序员很容易学习和使用. Java丢弃了C++中很少使用的.很难理解的.令人迷惑的那些特性,如操作符重载.多继承.自动的强 ...

  3. STM32的引脚的配置

    http://blog.csdn.net/u010592722/article/details/45746079

  4. python3 xlrd包的用法

    一.xlrd的安装 pip install xlrd 二.xlrd使用介绍 1.导入模块 import xlrd 2.打开Excel文件,实例化为readbook readbook = xlrd.op ...

  5. ubuntu 14.04安装mysql-python

    网上看到的是想安装mysql-python都得安装mysql本身,可是我就不想安装这个数据库,而是用于连接到别的服务器上的mysql,所以下面就是安装过程: 1. 直接运行: pip install ...

  6. Linux :忘记使用nohup该如何补救

    Linux :忘记使用nohup该如何补救 目录 Linux :忘记使用nohup该如何补救 0x00 摘要 0x01 问题描述 1.1 为何关闭进程 1.2 nohup 作用 0x02 简述 2.1 ...

  7. python字典转bytes类型字典

    python字典转bytes类型字典import base64 import json 1. a={"Vod":{"userData":"{}&quo ...

  8. 干货:ANR日志分析全面解析

    一.概述 解决ANR一直是Android 开发者需要掌握的重要技巧,一般从三个方面着手. 开发阶段:通过工具检查各个方法的耗时,卡顿情况,发现一处修改一处. 线上阶段:这个阶段主要依靠监控工具发现AN ...

  9. docker磁盘空间清理办法

    docker磁盘空间清理办法 前段时间遇到docker磁盘空间太少,无法写入数据的问题.起因是因为我在本地(Mac Pro)运行了多个mysql容器,并且导入了一部分线上数据,最后还没导入完毕就已经没 ...

  10. YOLOv4 资源环境配置和测试样例效果

    YOLOv4 资源环境配置和测试样例效果 基本环境:cuda=10.0,cudnn>=7.0, opencv>=2.4 一.下载yolov4 git clone https://githu ...