题目大意:

国王有一片森林,巫师需要从所有树中选出一些做成围栏把其他树围起来,

每棵树都有其对应的价值 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 /// 状压+凸包的更多相关文章

  1. POJ 2923 状压好题

    Relocation Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2631   Accepted: 1075 Descri ...

  2. POJ 3254 (状压DP) Corn Fields

    基础的状压DP,因为是将状态压缩到一个整数中,所以会涉及到很多比较巧妙的位运算. 我们可以先把输入中每行的01压缩成一个整数. 判断一个状态是否有相邻1: 如果 x & (x << ...

  3. POJ 3254 状压DP

    题目大意: 一个农民有一片n行m列 的农场   n和m 范围[1,12]  对于每一块土地 ,1代表可以种地,0代表不能种. 因为农夫要种草喂牛,牛吃草不能挨着,所以农夫种菜的每一块都不能有公共边. ...

  4. poj 1170状压dp

    题目链接:https://vjudge.net/problem/POJ-1170 题意:输入n,表示有那种物品,接下来n行,每行a,b,c三个变量,a表示物品种类,b是物品数量,c代表物品的单价.接下 ...

  5. POJ 2411 状压DP经典

    Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 16771   Accepted: 968 ...

  6. poj 3254 状压dp入门题

    1.poj 3254  Corn Fields    状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...

  7. poj 1185(状压dp)

    题目链接:http://poj.org/problem?id=1185 思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到 ...

  8. poj 1185 状压dp+优化

    http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 291 ...

  9. POJ 2441 状压DP

    Arrange the Bulls Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 5289   Accepted: 2033 ...

随机推荐

  1. scala中函数简单使用记录

    object funcHighLevel { def main(args: Array[String]): Unit = { // 创建一个匿名函数 val sayFunc = (name: Stri ...

  2. zookeeper中controller项目中资源配置文件applicationContext.xml配置文件编写

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  3. 绘制delphi窗体的标题栏

    绘制delphi窗体的标题栏 按照设计,Delphi窗体的“标题”属性是由Windows负责绘制,标题栏在系统菜单旁边.如果你不想改变窗体的标题属性又想在窗体的标题栏添加一些自己的内容,你需要处理一个 ...

  4. kafka保证数据不丢失机制

    kafka如何保证数据的不丢失 1.生产者如何保证数据的不丢失:消息的确认机制,使用ack机制我们可以配置我们的消息不丢失机制为-1,保证我们的partition的leader与follower都保存 ...

  5. NX二次开发-算法篇-vector函数排序(例子:遍历所有点并排序)

    NX9+VS2012 #include <uf.h> #include <uf_ui.h> #include <uf_curve.h> #include <u ...

  6. 隐藏tomcat页面异常显示的版本信息

    1.正常情况下,tomcat遇到404或500会返回版本信息: 2.有时我们不需要暴露版本信息,像这样: 3.只需要修改apache-tomcat-7.0.59的lib目录下的catalina.jar ...

  7. Spring随笔-bean装配-自动装配

    Spring提供了三种装配方式 1.XML文件进行显式装配 2.java中进行显示装配 3.自动化装配 1.自动化装配的两种实现方式 1.组件扫描:Spring会自动发现应用上下文中创建的bean 2 ...

  8. Memory barrier,

    A memory barrier, also known as a membar, memory fence or fence instruction, 是一种屏障指令,它使中央处理单元(CPU)或编 ...

  9. Android Telephony分析(一) ---- Phone详解

    目录: Phone的继承关系与PhoneFactory(GsmCdmaPhone.ImsPhone.SipPhone) Phone进程的启动 Phone对象的初始化(DefaultPhoneNotif ...

  10. scrapy的使用-Request

    Request对象在我们写爬虫,爬取一页的数据需要重新发送一个请求的时候调用.这个类需要传递一些参数.其中比较常用的参数有: 1.url    请求的url对象 2.callback  在下载器下载完 ...