题链:

http://poj.org/problem?id=1873

题解:

计算几何,凸包

枚举被砍的树的集合。求出剩下点的凸包。然后判断即可。

代码:

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=16,INF=0x3f3f3f3f;
const double eps=1e-8;
int sign(double x){
if(fabs(x)<=eps) return 0;
return x<0?-1:1;
}
struct Point{
double x,y;
Point(double _x=0,double _y=0):x(_x),y(_y){}
void Read(){scanf("%lf%lf",&x,&y);}
}D[MAXN],H[MAXN];
typedef Point Vector;
bool operator < (Point A,Point B){return sign(A.x-B.x)<0||(sign(A.x-B.x)==0&&sign(A.y-B.y)<0);}
bool operator == (Point A,Point B){return sign(A.x-B.x)==0&&sign(A.y-B.y)==0;}
Vector operator - (Point A,Point B){return Vector(A.x-B.x,A.y-B.y);}
double operator ^ (Vector A,Vector B){return A.x*B.y-A.y*B.x;}
double operator * (Vector A,Vector B){return A.x*B.x+A.y*B.y;}
int V[MAXN],N,ansS,ansV,ansN;
double L[MAXN],resL;
double GL(Vector A){//Get_Length
return sqrt(A*A);
}
int Andrew(int S){
int hnt=0,k=0,tnt=0;
static Point tmp[MAXN];
for(int i=1;i<=N;i++) if(!(S&(1<<(i-1)))) tmp[++tnt]=D[i];
sort(tmp+1,tmp+tnt+1);
tnt=unique(tmp+1,tmp+tnt+1)-tmp-1;
for(int i=1;i<=tnt;i++){
while(hnt>1&&sign((H[hnt]-H[hnt-1])^(tmp[i]-H[hnt-1]))<=0) hnt--;
H[++hnt]=tmp[i];
} k=hnt;
for(int i=tnt-1;i>=1;i--){
while(hnt>k&&sign((H[hnt]-H[hnt-1])^(tmp[i]-H[hnt-1]))<=0) hnt--;
H[++hnt]=tmp[i];
}
return hnt;
}
double GCPC(int hnt){//Get_Convex_Polygon_Circumference
double C=0;
for(int i=1;i<hnt;i++) C+=GL(H[i+1]-H[i]);
return C;
}
int main(){
double C,nowL;
int nowS,nowV,nowN,Case=0;
while(scanf("%d",&N)&&N){
if(N==0) break;
ansS=(1<<N)-1; ansV=INF; ansN=N; resL=0;
for(int i=1;i<=N;i++)
D[i].Read(),scanf("%d%lf",&V[i],&L[i]);
for(int S=1;S<=(1<<N)-1;S++){
nowS=S; nowN=0; nowL=0; nowV=0;
for(int i=1;i<=N;i++) if(S&(1<<(i-1)))
nowN++,nowV+=V[i],nowL+=L[i];
C=GCPC(Andrew(S));
if(sign(nowL-C)<0) continue;
if(nowV<ansV||(nowV==ansV&&nowN<ansN))
ansS=nowS,ansV=nowV,ansN=nowN,resL=nowL-C;
}
if (Case) puts("");
printf("Forest %d\n",++Case);
printf("Cut these trees:");
for(int i=1;i<=N;i++) if(ansS&(1<<(i-1))) printf(" %d",i);
printf("\nExtra wood: %.2lf\n",resL);
}
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(凸包)题解

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

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

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

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

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

  5. POJ 1873 The Fortified Forest

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

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

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

  7. POJ 1873 The Fortified Forest 凸包 二进制枚举

    n最大15,二进制枚举不会超时.枚举不被砍掉的树,然后求凸包 #include<stdio.h> #include<math.h> #include<algorithm& ...

  8. poj 1873 凸包+枚举

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

  9. Uva5211/POJ1873 The Fortified Forest 凸包

    LINK 题意:给出点集,每个点有个价值v和长度l,问把其中几个点取掉,用这几个点的长度能把剩下的点围住,要求剩下的点价值和最大,拿掉的点最少且剩余长度最长. 思路:1999WF中的水题.考虑到其点的 ...

随机推荐

  1. C++类型萃取

    stl中的迭代器和C++中的类型萃取: http://www.itnose.net/detail/6487058.html 赐教!

  2. 最短路算法模板SPFA、disjkstra、Floyd

    朴素SPFA(链表建边) #include <iostream> #include <cstdio> #include <cstring> #include < ...

  3. 纯CSS垂直居中的四种解决方案

    总结了几种解决方法 但也不是说除了我说的就没有其他方法了 第一个.利用flex布局 代码: 效果: 第二个.利用transform 的 translate属性 代码: 效果: 第三个.使用伪类::af ...

  4. Python模块configparser(操作配置文件ini)

    configparser模块提供对ini文件的增删改查方法. ini文件的数据格式: [name1] attribute1=value1 attribute2=value2 [name2] attri ...

  5. SQL SERVER 游标的使用

    首先,关于什么是游标大家可以看看这篇文章,介绍得非常详细!! SQL Server基础之游标 下面是我自己的应用场景-- 有个需求,需要把数据库表里面某一个字段的值设为随机不重复的值. 表是这样的: ...

  6. ajax 操作

    ajax 操作 ajax呢,就是要做到在神不知鬼不觉的情况之下给服务端发送请求. ajax能干啥哩? 这,,,,: 利用AJAX可以做:1.注册时,输入用户名自动检测用户是否已经存在.2.登陆时,提示 ...

  7. Python基础数据类型之集合以及其他和深浅copy

    一.基础数据类型汇总补充 list  在循环一个列表时,最好不要删除列表中的元素,这样会使索引发生改变,从而报错(可以从后向前循环删除,这样不会改变未删元素的索引). 错误示范: lis = [,,, ...

  8. 使用 C#/.NET Core 实现单体设计模式

    本文的概念内容来自深入浅出设计模式一书 由于我在给公司做内培, 所以最近天天写设计模式的文章.... 单体模式 Singleton 单体模式的目标就是只创建一个实例. 实际中有很多种对象我们可能只需要 ...

  9. 上传视频使用ffmpeg自动截取缩略图

    上传视频之后,有的需要显示缩略图,而不是仅仅显示视频名称的列表,这时候就需要对上传的视频截取缩略图. 简单粗暴点,将以下代码作为工具类复制粘贴即可: package com.util; import ...

  10. [LuoguP1113] 杂物 - 拓扑排序

    其实只是纪念下第一篇洛谷题解? Description John的农场在给奶牛挤奶前有很多杂务要完成,每一项杂务都需要一定的时间来完成它.比如:他们要将奶牛集合起来,将他们赶进牛棚,为奶牛清洗乳房以及 ...