题目大意:

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

每棵树都有其对应的价值 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. Ruby 命令行选项

    Ruby 命令行选项 Ruby 一般是从命令行运行,方式如下: $ ruby [ options ] [.] [ programfile ] [ arguments ... ] 解释器可以通过下列选项 ...

  2. 依赖背包变形——hdu4003

    思维性比较强,代码挺简单的,dp[u][j]表示在u子树下安排j个机器人,让其不回u 注意转移时的初始值 /* dp[u][j]为在子树u有j个机器人不回来 */ #include<bits/s ...

  3. 6 Accessing and Managing Symbols with armlink

    6.4 Image$$ execution region symbols The linker generates Image$$ symbols for every execution region ...

  4. solr 如何实现精确查询

    第一条和第三条不应该出现的. 解决办法

  5. 【POJ】2492 A Bug's Life

    题目链接:http://poj.org/problem?id=2492 题意:给你n个虫子,m组实验.让你帮科学家找一下有没有虫子是同性恋. 题解:假设x是一个性别,x+n为另一个性别.如果在同性的集 ...

  6. PostgreSQL 主键自动增长

    建立主键并设置自动增加的办法好好几种,这里记录我测试过的: drop table pro_process; CREATE TABLE "public"."pro_proc ...

  7. 2019-8-31-C#-通过编程的方法在桌面创建回收站快捷方式

    title author date CreateTime categories C# 通过编程的方法在桌面创建回收站快捷方式 lindexi 2019-08-31 16:55:58 +0800 201 ...

  8. EXCEL表格链接SQLSEVER数据库

    Sub 数据库连接()     Set Cnn = CreateObject("ADODB.Connection")    Set rs = CreateObject(" ...

  9. Dubbo的底层实现原理和机制

    –高性能和透明化的RPC远程服务调用方案 –SOA服务治理方案 Dubbo缺省协议采用单一长连接和NIO异步通讯, 适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况

  10. 学习 Apache FileMatchs 规则

    # 凡是匹配到 zip,gz,rar,box,log结尾的文件,进行下面的规则进行匹配 <filesmatch ".(zip|gz|rar|box|log)"> Ord ...