题意:二维平面有一堆点,每个点有价值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. Springboot杂七杂八

    1 加载配置文件 private static ResourceBundle resb = ResourceBundle.getBundle("serverInfo"); 然后在r ...

  2. 139. Word Break(动态规划)

    Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine ...

  3. sitecore系统教程之内容编辑器

    内容编辑器   内容编辑器是一种编辑工具,可用于管理和编辑网站上的所有内容.它专为熟悉Sitecore及其包含的功能的经验丰富的内容作者而设计. 内容编辑器的外观和功能取决于用户的角色,本地安全设置以 ...

  4. Hibernate,关系映射的多对一单向关联、多对一双向关联、一对一主键关联、一对一外键关联、多对多关系关联

    2018-11-10  22:27:02开始写 下图内容ORM.Hibernate介绍.hibername.cfg.xml结构: 下图内容hibernate映射文件结构介绍 下图内容hibernate ...

  5. Python -- print(dataframe)时,省略部分列。

    import pandas as pd # 导入后加入以下列,再显示时显示完全. pd.set_option('display.max_rows',500) pd.set_option('displa ...

  6. 入坑tensorflow

    win10 CPU版,anaconda prompt命令行一句话,pip install --upgrade tensorflow搞定.比caffe好装一万倍. gpu版没装成,首先这个笔记本没装cu ...

  7. HTML转义符

    空格的替代符号有以下几种: 名称 编号 描述   &#; 不断行的空白(1个字符宽度)   &#; 半个空白(1个字符宽度)   &#; 一个空白(2个字符宽度)   & ...

  8. redis的数据类型命令

    存储sortedset: 存储:zadd key score menber1 score menber2 ... 升序排列:zrange key start end [withscores] 降序排列 ...

  9. STO(Security Token Offering)证券型通证、代币发行介绍

    STO(Security Token Offering)证券型通证.代币发行介绍:STO(Security Token Offering)是一个新的融资概念.通过证券化的通证进行融资.早在2017年年 ...

  10. android使用inject需要注意的地方

    android使用inject需要注意的地方1.viewmodel里面添加注解@Inject FavoritesDBManager mFavoritesDBManager; 2.Component里面 ...