题意:二维平面有一堆点,每个点有价值v和删掉这个点能得到的长度l,问你删掉最少的价值能把剩余点围起来,价值一样求删掉的点最少

思路:n<=15,那么直接遍历2^15,判断每种情况。这里要优化一下,如果价值比当前最优大了continue。POJ的G++输出要用%f...orz,还是乖乖用C++...

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
struct node{
double x, y, l;
int v, id;
}p[maxn], s[maxn], q[maxn];
int n, top;
double dis(node a, node b){
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool cmp(node a, node b){
double A = atan2((a.y - p[].y), (a.x - p[].x));
double B = atan2((b.y - p[].y), (b.x - p[].x));
if(A != B) return A < B;
else{
return dis(a, p[]) < dis(b, p[]);
}
}
double cross(node a, node b, node c){ //(a->b)X(a->c)
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
void solve(){
int pos = ;
for(int i = ; i <= n; i++){
if(p[i].y < p[pos].y || (p[i].y == p[pos].y && p[i].x < p[pos].x)){
pos = i;
}
}
swap(p[], p[pos]);
sort(p + , p + n + , cmp);
s[] = p[], s[] = p[];
top = ;
for(int i = ; i <= n; i++){
while(top >= && cross(s[top - ], p[i], s[top]) >= ){
top--;
}
s[++top] = p[i];
}
}
double need(double len){
if(n <= ) return len;
if(n == ){
return len - 2.0 * dis(p[], p[]);
}
solve();
double Need = ;
for(int i = ; i < top; i++){
Need += dis(s[i], s[i + ]);
}
Need += dis(s[top], s[]);
return len - Need;
}
int main(){
int N, ca = ;
while(~scanf("%d", &N) && N){
for(int i = ; i < N; i++){
scanf("%lf%lf%d%lf", &q[i].x, &q[i].y, &q[i].v, &q[i].l);
q[i].id = i + ;
}
int sz = , que[], tempQue[];
int MinValue = INF;
double ans = ;
for(int i = ; i < ( << N); i++){
int num = , value = ;
double len = ;
n = ;
for(int j = ; j < N; j++){
if(i & ( << j)){
p[++n] = q[j];
}
else{
value += q[j].v;
len += q[j].l;
tempQue[num] = q[j].id;
num++;
}
}
if(value > MinValue) continue;
double tmp = need(len);
if(tmp < ) continue;
if(value < MinValue || (value == MinValue && num < sz)){
MinValue = value;
ans = tmp;
sz = num;
for(int j = ; j < num; j++){
que[j] = tempQue[j];
}
}
}
if(ca != ) printf("\n");
printf("Forest %d\n", ca++);
printf("Cut these trees: ");
for(int i = ; i < sz; i++){
printf("%d ", que[i]);
}
printf("\n");
printf("Extra wood: %.2lf\n", ans);
}
return ;
}

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 凸包 + 搜索 模板

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

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

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

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

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

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

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

  6. ●POJ 1873 The Fortified Forest

    题链: http://poj.org/problem?id=1873 题解: 计算几何,凸包 枚举被砍的树的集合.求出剩下点的凸包.然后判断即可. 代码: #include<cmath> ...

  7. POJ 1873 The Fortified Forest

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

  8. poj1873 The Fortified Forest 凸包+枚举 水题

    /* poj1873 The Fortified Forest 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...

  9. Uva5211/POJ1873 The Fortified Forest 凸包

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

随机推荐

  1. <1>Cocos Creator安装和启动

    学习之间需要了解JavaScritp基本语法和面向对象,详情参考https://blog.csdn.net/jadeshu/article/category/7476938 1.下载Cocos Cre ...

  2. 开源词袋模型DBow3原理&源码(二)ORB特征的保存和读取

    util里提供了create_voc_step0用于批量生成features并保存,create_voc_step1读入features再生成聚类中心,比较适合大量语料库聚类中心的生成. 提取一张图的 ...

  3. Hive 的排名和跨行 窗口函数及其使用

    一.排序&去重分析 row_number() over(partititon by col1 order by col2) as rn 也可以用 row_number() over(distr ...

  4. c# 对话框控件

    对话框也是一种窗体,通常调用对对话框相关类型的ShowDialog方法来弹出对话框,当用户关闭对话框后,该方法会返回一个DialogResult枚举值,通过该值就可以判断用户采取了什么操作,例如单击确 ...

  5. let的使用 优先于闭包

    let声明的变量在{}中使用,变量的作用域限制在块级域中 举例:使用js动态给ul添加li对象并点击第几项,显示当前点击是第几个 错误代码 window.onload = function(){ va ...

  6. centos 安装arcgis server 10.1

    1.创建新用户,不要在root下面直接安装 [root@localhost ~]# groupadd esri //创建esri组 [root@localhost ~]# useradd ags -g ...

  7. vue路由5:命名视图

    <div id="app"> <div> <router-link to="/">首页</router-link> ...

  8. [转载]Javascript:history.go()和history.back()的用法和区别

    Javascript:history.go()和history.back()的用法和区别 简单的说就是:go(-1): 返回上一页,原页面表单中的内容会丢失:back(): 返回上一页,原页表表单中的 ...

  9. 洛谷 P2799 国王的魔镜

    把项链当做字符串输进去,可以用gets #include<iostream>#include<cstdio>#include<cmath>#include<c ...

  10. Kali linux apt-get update 失败,无release……(最有效)

    设置源 编辑 /etc/apt/sources.list nano /etc/apt/sources.list 清空文件内所有内容后添加 deb http://mirrors.ustc.edu.cn/ ...