题目大意:有个国王他有一片森林,现在他想从这个森林里面砍伐一些树木做成篱笆把剩下的树木围起来,已知每个树都有不同的价值还有高度,求出来砍掉那些树可以做成篱笆把剩余的树都围起来,要使砍伐的树木的价值最小,如果有价值相同的尽量使砍伐的树木少一些。

分析:因为树木的数量是比较少的,所以枚举所有的状态,判断那个树需要砍那个树不需要,然后按照要求求出来答案即可。

代码如下:

==============================================================================================

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std; const double EPS = 1e-;
const int MAXN = ;
const int oo = 1e9+; int vi[MAXN], li[MAXN], sta[MAXN], top; struct point
{
double x, y; point(double x=, double y=):x(x), y(y){}
point operator - (const point &t)const{
return point(x-t.x, y-t.y);
}
double operator *(const point &t)const{
return x*t.x + y*t.y;
}
double operator ^(const point &t)const{
return x*t.y - y*t.x;
}
}p[MAXN], date[MAXN];
int Sign(double t)
{
if(t > EPS)return ;
if(fabs(t) < EPS)return ;
return -;
}
double Dist(point a, point b)
{
return sqrt((a-b)*(a-b));
}
bool cmp(point a, point b)
{
int t = Sign((a-p[])^(b-p[])); if(t == )
return Dist(a, p[]) < Dist(b, p[]);
return t > ;
}
void Graham(int N)
{
int k=; for(int i=; i<N; i++)
{
if(p[k].y>p[i].y || (Sign(p[k].y-p[i].y)== && p[k].x > p[i].x))
k = i;
}
swap(p[], p[k]);
sort(p+, p+N, cmp); sta[]=, sta[]=, top=; if(N < )
{
top = N-;
return ;
} for(int i=; i<N; i++)
{
while(top> && Sign((p[i]-p[sta[top]])^(p[sta[top-]]-p[sta[top]])) <= )
top--;
sta[++top] = i;
}
}
bool Solve(int bitNum, int N, int &val, int &nOne, double &lastLen)
{
int cut_val=, cnt=, cut_len=; for(int i=; i<N; i++)
{
if(bitNum & )
{
cut_val += vi[i];
cut_len += li[i];
}
else
p[cnt++] = date[i];
bitNum >>= ;
} Graham(cnt); double len=;
sta[++top] = sta[]; for(int i=; i<=top; i++)
{
len += Dist(p[sta[i]], p[sta[i+]]);
} if(Sign(cut_len-len) >= && (val > cut_val || (val==cut_val&&nOne > N-cnt)))
{
lastLen = cut_len - len;
val = cut_val;
nOne = N-cnt;
return true;
}
return false;
} int main()
{
int N, t=; while(scanf("%d", &N), N)
{
int val=oo, ans, nOne=oo;
double lastLen; for(int i=; i<N; i++)
scanf("%lf%lf%d%d", &date[i].x, &date[i].y, &vi[i], &li[i]); int Len = (<<N)-; for(int i=; i<Len; i++)
{
if(Solve(i, N, val, nOne, lastLen) == true)
ans = i;
}
if(t!=)printf("\n");
printf("Forest %d\n", t++);
printf("Cut these trees:");
for(int i=; ans; i++)
{
if(ans & )
printf(" %d", i);
ans >>= ;
}
printf("\nExtra wood: %.2f\n", lastLen);
} return ;
}

The Fortified Forest - POJ 1873(状态枚举+求凸包周长)的更多相关文章

  1. poj1873(二进制枚举+求凸包周长)

    题目链接:https://vjudge.net/problem/POJ-1873 题意:n个点(2<=n<=15),给出n个点的坐标(x,y).价值v.做篱笆时的长度l,求选择哪些点来做篱 ...

  2. poj 1113:Wall(计算几何,求凸包周长)

    Wall Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 28462   Accepted: 9498 Description ...

  3. POJ 1113 Wall(Graham求凸包周长)

    题目链接 题意 : 求凸包周长+一个完整的圆周长. 因为走一圈,经过拐点时,所形成的扇形的内角和是360度,故一个完整的圆. 思路 : 求出凸包来,然后加上圆的周长 #include <stdi ...

  4. HDU 1392 凸包模板题,求凸包周长

    1.HDU 1392 Surround the Trees 2.题意:就是求凸包周长 3.总结:第一次做计算几何,没办法,还是看了大牛的博客 #include<iostream> #inc ...

  5. Wall---hdu1348(求凸包周长 模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 求凸包周长+2*PI*L: #include <stdio.h> #include ...

  6. hdu 1392:Surround the Trees(计算几何,求凸包周长)

    Surround the Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  7. hdu 1348:Wall(计算几何,求凸包周长)

    Wall Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  8. poj 1873(枚举所有的状态+凸包)

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

  9. POJ 2187 Beauty Contest【凸包周长】

    题目: http://poj.org/problem?id=1113 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

随机推荐

  1. PAT_1018 锤子剪刀布

    问题描述 大家应该都会玩“锤子剪刀布”的游戏:两人同时给出手势,胜负规则如图所示: 现给出两人的交锋记录,请统计双方的胜.平.负次数,并且给出双方分别出什么手势的胜算最大. 输入格式: 输入第1行给出 ...

  2. MFC中cannot find the definition (implementation) of this function 解决方法

    问题:使用vc6 在点击左侧class view中的一个方法实现时出现下面错误:    cannot find the definition (implementation) of this func ...

  3. python 计算apache进程占用的内存大小以及占物理内存的比例

      目的:计算所有apache进程占用的内存大小以及占物理内存的比例: 思路:利用系统中/proc/meminfo的现有数据进行统计 1.pidof列出服务对应进程的PID [root@yanglih ...

  4. YZOI Easy Round 2_化简(simplify.c/cpp/pas)

    Description 给定一个多项式,输出其化简后的结果. Input 一个字符串,只含有关于字母x 的多项式,不含括号与分式,没有多余的空格. Output 一个字符串,化简后的多项式,按照次数从 ...

  5. css 文本两端对齐

    在做表单时我们经常遇到让上下两个字段对齐的情况,比如姓名, 手机号码, 出生地.这样我们就要用到 text-align, text-justify样式了. text-align直接设为justify就 ...

  6. Centos安装编译环境

    众所周知,在安装完Centos完了以后,是没有编译环境的,我自己挂上光盘,手动安装解决了几十的依赖关系,在配置些软件时,还是经常报些依赖软件包的缺失,很是头疼,后来百度了下centos需要装的编译环境 ...

  7. quick-x 触摸事件的新方法

    --[[ local function onTouch(event, x, y) print(event, x, y) if event == "began" then retur ...

  8. 2016022605 - redis订阅发布

    Redis的实现消息队列功能,消息发布者发送的消息,消息接收者接收发布者的消息.由该消息传送的链路被称为通道.在Redis客户端可以订阅任何数目的通道. 案例:给出一个客户端订阅一个通道名为redis ...

  9. 扩展原生js的一些方法

    扩展原生js的Array类 Array.prototype.add = function(item){ this.push(item); } Array.prototype.addRange = fu ...

  10. CSS样式的优先级

    1.相同权值情况下,CSS样式的优先级总结来说,就是--就近原则(离被设置元素越近优先级别越高): 内联样式表(标签内部)> 嵌入样式表(当前文件中)> 外部样式表(外部文件中). 2.权 ...