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. ZooKeeper IDEA 可视化管理插件安装

    1. 安装 zookeeper 插件 打开 IDEA->Settings->Plugins,然后在 Marketplace 输入 "zookeeper" 如下: 插件安 ...

  2. HDFS 高可用(HA)环境搭建

    步骤一:修改公共属性配置 core-site.xml 文件 [root@node-01 ~]# cd /root/apps/hadoop-3.2.1/etc/hadoop [root@node-01 ...

  3. Redis 为什么使用跳跃表

    引言 跳跃表是一种有序的数据结构,它通过在每个节点中维持多个指向其他节点的指针,从而达到快速访问节点的目的. 什么是跳跃表 对于一个单链表来讲,即便链表中存储的数据是有序的,如果我们要想在其中查找某个 ...

  4. Canal--服务端和客户端搭建

    服务端 源码编译 git clone https://github.com/alibaba/canal.git 用IDEA打开克隆的项目 等待maven下载完依赖后开始编译过程 依赖下载完成后,打开m ...

  5. Centos7.4 docker安装包下载以及离线安装

    docker安装包下载地址:https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ 需要下载一个selinux包:dock ...

  6. .NET6系列:Visual Studio 2022 线路图

    系列目录     [已更新最新开发文章,点击查看详细] 在上一篇博客<Visual Studio 2022>中介绍了VS2022的性能改进与重要功能.本文主要介绍在 Visual Stud ...

  7. JS中的高阶函数

    JS中的高阶函数 高阶函数是指以函数作为参数的函数,并且可以将函数作为结果返回的函数. 1. 高阶函数 接受一个或多个函数作为输入 输出一个函数 至少满足以上一个条件的函数 在js的内置对象中同样存在 ...

  8. 第4讲 | DHCP与PXE:IP是怎么来的,又是怎么没的?

    第4讲 | DHCP与PXE:IP是怎么来的,又是怎么没的? linux 配置网络IP地址: 使用 net-tools: sudo ifconfig eth1 10.0.0.1/24 sudo ifc ...

  9. Step By Step(Lua迭代器和泛型for)

    Step By Step(Lua迭代器和泛型for) 1. 迭代器与Closure:    在Lua中,迭代器通常为函数,每调用一次函数,即返回集合中的"下一个"元素.每个迭代器都 ...

  10. Go语言介绍(背景、特点)

    一.go语言的背景 Go是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Go(又称 Golang)是 Google 的 Rob Pike(罗勃.派克),Ken Thompson(肯· ...