POJ 1873 /// 状压+凸包
题目大意:
国王有一片森林,巫师需要从所有树中选出一些做成围栏把其他树围起来,
每棵树都有其对应的价值 v 和能作为围栏的长度 l
要求最小价值,若存在多种最小价值的方案则选择余下长度更少的
树木较少 状态压缩 枚举所有状态
计算当前的状态 被选中的 树的价值和长度
其他 被围起来(未被选中)的树去求凸包
计算凸包的边长(即围栏的最小长度)
判断选中的树是否能围住凸包 再更新答案
#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
using namespace std; const double eps=1e-;
double add(double a,double b) {
if(abs(a+b)<eps*(abs(a)+abs(b))) return ;
return a+b;
}
struct P {
double x,y;
P(){};
P(double _x,double _y):x(_x),y(_y){};
P operator - (P p) {
return P(add(x,-p.x),add(y,-p.y)); }
P operator + (P p) {
return P(add(x,p.x),add(y,p.y)); }
P operator * (double d) {
return P(x*d,y*d); }
double dot(P p) {
return add(x*p.x,y*p.y); }
double det(P p) {
return add(x*p.y,-y*p.x); }
}p1[], p2[], p3[];
int n;
double v[], l[], ansv, ansl;
bool cmp(P a,P b) {
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
double length(P a,P b) {
return sqrt((a-b).dot(a-b));
}
double andrew(int n)
{
sort(p2,p2+n,cmp);
int k=;
for(int i=;i<n;i++) {
while(k> && (p3[k-]-p3[k-]).det(p2[i]-p3[k-])<=)
k--;
p3[k++]=p2[i];
}
for(int i=n-,t=k;i>=;i--) {
while(k>t && (p3[k-]-p3[k-]).det(p2[i]-p3[k-])<=)
k--;
p3[k++]=p2[i];
} // 凸包上的点存入p3 double res=;
for(int i=;i<k;i++) // 计算凸包边长 即围栏长度
res+=length(p3[i],p3[i-]);
return res;
}
bool solve(int task)
{
int cnt=, t=task;
double cntv=, cntl=;
for(int i=;i<n;i++) {
if(task&) cntv+=v[i], cntl+=l[i]; // 被选中的 计算价值及长度
else p2[cnt++]=p1[i]; // 为被选中的存入p2 待求凸包
task >>= ;
}
if(cntv>ansv) return ; // 价值大于已有答案价值 返回0
double tblen=andrew(cnt); // 求凸包边长 即围栏所需长度
if(tblen>cntl) return ; // 若长度不足于围成围栏 返回0 if(cntv==ansv) ansl=min(ansl,cntl-tblen); // 更新余下长度的答案
else ansv=cntv, ansl=cntl-tblen; // 存在更小的价值 更新价值和长度
return ; // 更新了答案 返回1 记录新的状态
} int main()
{
int c=;
while(~scanf("%d",&n)) {
if(n==) break; c++;
for(int i=;i<n;i++) {
scanf("%lf%lf",&p1[i].x,&p1[i].y);
scanf("%lf%lf",&v[i],&l[i]);
} int ans;
ansv=ansl=INF;
int N=(<<n)-;
for(int i=;i<N;i++) // 枚举所有状态
if(solve(i)) ans=i; printf("Forest %d\n",c);
printf("Cut these trees:");
for(int i=;i<n;i++) {
if(ans & ) printf(" %d",i+);
ans >>= ;
}
printf("\nExtra wood: %.2f\n\n",ansl);
} return ;
}
POJ 1873 /// 状压+凸包的更多相关文章
- POJ 2923 状压好题
Relocation Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2631 Accepted: 1075 Descri ...
- POJ 3254 (状压DP) Corn Fields
基础的状压DP,因为是将状态压缩到一个整数中,所以会涉及到很多比较巧妙的位运算. 我们可以先把输入中每行的01压缩成一个整数. 判断一个状态是否有相邻1: 如果 x & (x << ...
- POJ 3254 状压DP
题目大意: 一个农民有一片n行m列 的农场 n和m 范围[1,12] 对于每一块土地 ,1代表可以种地,0代表不能种. 因为农夫要种草喂牛,牛吃草不能挨着,所以农夫种菜的每一块都不能有公共边. ...
- poj 1170状压dp
题目链接:https://vjudge.net/problem/POJ-1170 题意:输入n,表示有那种物品,接下来n行,每行a,b,c三个变量,a表示物品种类,b是物品数量,c代表物品的单价.接下 ...
- POJ 2411 状压DP经典
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 16771 Accepted: 968 ...
- poj 3254 状压dp入门题
1.poj 3254 Corn Fields 状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...
- poj 1185(状压dp)
题目链接:http://poj.org/problem?id=1185 思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到 ...
- poj 1185 状压dp+优化
http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 291 ...
- POJ 2441 状压DP
Arrange the Bulls Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 5289 Accepted: 2033 ...
随机推荐
- 扩展欧几里得原理的应用:POJ1061青蛙的约会
/* POJ 1061: 青蛙的约会 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 123709 Accepted: 26395 ...
- bzoj1045题解
[解题思路] (数据范围劝退?正确范围应该是n≤1000000) 设xi表示第i个小朋友给第i+1个小朋友的糖果数(特殊的,xn表示第n个小朋友给第1个小朋友的糖果数),Â表示平均糖果数,有如下方程组 ...
- 移动端图片轮播效果:depth模式总结
最近公司app改版首页增加了一处轮播图效果,但是跟普通的轮播效果不同,是类似于下图的样式,找了一些兼容移动端的插件以及jQuery源码,总结一下使用心得: 1:jquery源码:缺点是在手机端的滑动很 ...
- NX二次开发-UFUN获取边的端点UF_MODL_ask_edge_verts
NX9+VS2012 #include <uf.h> #include <uf_modl.h> #include <uf_ui.h> #include <uf ...
- 7.RabbitMQ RFC同步调用
RabbitMQ RFC同步调用是使用了两个异步调用完成的,生产者调用消费者的同时,自己也作为消费者等待某一队列的返回消息,消费者接受到生产者的消息同时,也作为消息发送者发送一消息给生产者.参考下图: ...
- ionic-CSS:ionic tab(选项卡)
ylbtech-ionic-CSS:ionic tab(选项卡) 1.返回顶部 1. ionic tab(选项卡) ionic tab(选项卡) 是水平排列的按钮或者链接,用以页面间导航的切换.它可以 ...
- Oracle Net Configuration Assistant failed异常的解决方案
来自:http://blog.itpub.net/25851087/viewspace-1419440/ 分类: Oracle [环境参数] Host OS::Win7 32bit C ...
- java 迷你DVD管理器
1.DvdSet类 package dvd_01; /** * 定义dvd的一些属性 * @author Administrator * */ public class DvdSet { String ...
- (转)lua protobuffer的实现
转自: http://www.voidcn.com/article/p-vmuovdgn-bam.html (1)lua实现protobuf的简介 需要读者对google的protobuf有一定的了解 ...
- python 的打开、读、写、追加操作
读f = open('D:\最新全栈python第2期视频教程 全套完整版\day08-python 全栈开发-基础篇\新建文本文档.txt','r') # data = f.read(10000)# ...