UVA 811 The Fortified Forest (凸包 + 状态压缩枚举)

题目链接:UVA 811

Description

Once upon a time,in a faraway land,there lived a king. This king owned a small collection of rare and valuable trees,which had been gathered by his ancestors on their travels. To protect his trees from thieves,the king ordered that a high fence be built around them. His wizard was put in charge of the operation.

Alas,the wizard quickly noticed that the only suitable material available to build the fence was the wood from the trees themselves. In other words,it was necessary to cut down some trees in order to build a fence around the remaining trees. Of course,to prevent his head from being chopped off,the wizard wanted to minimize the value of the trees that had to be cut. The wizard went to his tower and stayed there until he had found the best possible solution to the problem. The fence was then built and everyone lived happily ever after.

You are to write a program that solves the problem the wizard faced.

Input

The input contains several test cases,each of which describes a hypothetical forest. Each test case begins with a line containing a single integer \(n\),\(2\le n\le 15\),the number of trees in the forest. The trees are identied by consecutive integers \(1\) to \(n\). Each of the subsequent lines contains \(4\) integers \(x_i,y_i,v_i,l_i\) that describe a single tree. \((x_i,y_i)\) is the position of the tree in the plane,\(v_i\) is its value,and \(l_i\) is the length of fence that can be built using the wood of the tree. \(vi\) and \(li\) are between \(0\) and \(10,000\).

The input ends with an empty test case \((n = 0)\).

Output

For each test case,compute a subset of the trees such that,using the wood from that subset,the remaining trees can be enclosed in a single fence. Find the subset with minimum value. If more than one such minimum-value subset exists,choose one with the smallest number of trees. For simplicity,regard the trees as having zero diameter.

Display,as shown below,the test case numbers (1,2,...),the identity of each tree to be cut,and the length of the excess fencing (accurate to two fractional digits).

Display a blank line between test cases.

Sample Input

6
 0  0  8  3
 1  4  3  2
 2  1  7  1
 4  1  2  3
 3  5  4  6
 2  3  9  8
3
 3  0 10  2
 5  5 20 25
 7 -3 30 32
0

Sample Output

Forest 1
Cut these trees: 2 4 5 
Extra wood: 3.16

Forest 2
Cut these trees: 2 
Extra wood: 15.00

Solution

题意

\(n\) 颗树,每颗树的坐标为 \(x,y\) ,价值为 \(v_i\) 长度为 \(l_i\)。现在要用篱笆将其中一些树围起来,但篱笆制作来源于这些树,即要求砍掉的树能构成篱笆的长度 \(>=\) 剩余树的凸包周长。现在要使得砍掉树的价值之和最小,问需要砍掉哪些树(如果有价值相同的解,就输出砍的树最少的解)。

题解

凸包周长 状态压缩枚举

树的规模比较小,用二进制枚举所有情况即可。

Code

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
const double eps = 1e-8;
const int inf = 0x3f3f3f3f;
const int maxn = 15 + 10;

int n;
struct Point {
    double x,y;
    double v,l;
    int id;
    Point() {}
    Point(double a,double b) : x(a),y(b) {}
    bool operator<(const Point &b) const {
        if (x < b.x) return 1;
        if (x > b.x) return 0;
        return y < b.y;
    }
    Point operator-(const Point &b) {
        return Point(x - b.x,y - b.y);
    }
} p[maxn],stk[maxn],tmp[maxn];
typedef Point Vec;

int sgn(double x)  {
    if (fabs(x) <= eps)
        return 0;
    return x > 0 ? 1 : -1;
}

double dist(Point a,Point b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double cross(Vec a,Vec b) {
    return a.x * b.y - a.y * b.x;
}

int Andrew(int l) {
    int len = 0;
    for (int i = 1; i <= l; ++i) {
        while (len > 1 && sgn(cross(stk[len] - stk[len - 1],tmp[i] - stk[len - 1])) == -1) {
            len--;
        }
        stk[++len] = tmp[i];
    }
    int k = len;
    for (int i = l - 1; i >= 1; --i) {
        while (len > k && sgn(cross(stk[len] - stk[len - 1],tmp[i] - stk[len - 1])) == -1) {
            len--;
        }
        stk[++len] = tmp[i];
    }
    return len;
}

int main() {
    int kase = 0;
    while(cin >> n && n) {
        if(kase) printf("\n");  // 最后一行不输出空行,WA了好几次
        for (int i = 1; i <= n; ++i) {
            scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&p[i].v,&p[i].l);
            p[i].id = i;
        }
        sort(p + 1,p + 1 + n);

        double min_val = 1e8;
        double min_len;
        int min_num = inf;
        int min_state;
        int N = 1 << n;
        for(int i = 1; i < N; ++i) {
            double cur_len = 0;
            double cur_val = 0;
            int cur_num = 0;
            for(int j = 0; j < n; ++j) {
                if(!((i) & (1<<j)) ) {
                    cur_val += p[j + 1].v;
                    cur_len += p[j + 1].l;
                } else {
                    tmp[++cur_num] = p[j + 1];
                }
            }

            int t = Andrew(cur_num);
            double d = 0;
            for(int j = 1; j < t; ++j) {
                d += dist(stk[j],stk[j + 1]);
            }

            if(sgn(cur_len - d) >= 0) {
                if(sgn(min_val - cur_val) > 0 || (sgn(min_val - cur_val) == 0 && min_num > cur_num)) {
                    min_val = cur_val;
                    min_num = cur_num;
                    min_state = i;
                    min_len = cur_len - d;
                }
            }
            
        }

        printf("Forest %d\nCut these trees: ",++kase);
        vector<int> id;
        for(int i = 0; i < n; ++i) {
            if((~min_state) & (1 << i)) {
                id.push_back(p[i + 1].id);
            }
        }
        sort(id.begin(),id.end());
        for(int i = 0; i < id.size(); ++i) {
            printf("%d",id[i]);
            printf("%s",i == id.size() - 1? "\n": " ");
        }

        printf("Extra wood: %.2lf\n",min_len);
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1.github代码实践源代码是lua脚本语言,下载th之后运行thmain.lua-netTypevgg-savevgg_cifar10/-S0.0001,报错: 试看看安装lua:报错了,参考这篇文章:ubuntu18.04安装lua的步骤以及出现的问题_weixin_41355132的博客-CSDN博客问题解决,安装成功:情况并没有好转,出现相
此文为搬运帖,原帖地址https://www.cnblogs.com/zwywilliam/p/5999924.html前言在看了uwa之前发布的《Unity项目常见Lua解决方案性能比较》,决定动手写一篇关于lua+unity方案的性能优化文。整合lua是目前最强大的unity热更新方案,毕竟这是唯一可以支持ios热更新的办法。然而作
Rime输入法通过定义lua文件,可以实现获取当前时间日期的功能。1.TIMERime是一款可以高度自定义的输入法,相关教程可以查看往期文章,关于时间获取是指输入一个指定关键字,输出当前时间,效果如下(我定义了time关键字):实现如下:①在用户文件夹中新建一个rime.lua文件加入如下代码 ti
localfunctiongenerate_action(params)localscale_action=cc.ScaleTo:create(params.time,params.scale_x,params.scale_y)localfade_action=cc.FadeIn:create(params.time)returncc.Spawn:create(scale_action,fade_action)end
2022年1月11日13:57:45 官方:https://opm.openresty.org/官方文档:https://opm.openresty.org/docs#table-of-contents为什么建议使用opm不建议使用luarocks?http://openresty.org/cn/using-luarocks.html官方解释:请注意!LuaRocks并不是OpenResty官方推荐的装包方式。LuaRoc
在Lua中的table(表),就像c#中的HashMap(哈希表),key和value一一对应。元表:table的一个操作的拓展,里面包含关联了对应的方法,元方法就是其中一个。元方法:当你通过键来访问table的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index键。如果__inde
表排序:table.sort(list[,comp])参数list:指定表,可选参数comp:排序函数,无参数时通常按升序排序。排序函数针对表中连续的序列,其间不可以存在空洞或nil,排序函数需要两个形参(对应表中每次参加比较的两个数据),需要一个比较两个形参表达式的返回值,不能含有等于关系,例如>=,<=,==。do
一、安装lua环境1.1安装依赖包[root@centos7~]#yuminstallgccreadline-devel1.2下线lua源码包并解压[root@centos7~]#wgethttp://www.lua.org/ftp/lua-5.3.5.tar.gz[root@centos7~]#tarxvflua-5.3.5.tar.gz-C/usr/local/src1.3进行编译[root@centos7~]
官网OpenResty® 是一个基于 Nginx 与Lua的高性能Web平台,其内部集成了大量精良的Lua库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态Web应用、Web服务和动态网关。OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由
表参考《lua程序设计》可以认为,表是一种动态分配的对象,程序只能操作指向表的引用(或指针)。除此以外,Lua语言不会进行隐藏的拷贝(hiddencopies)或创建新的表--创建表a={}--创建空表k="x"a[k]=10--键“x”值10a[20]="great"--键20值“great”print(a["x"])-->10
https://github.com/galenho/crossover.git一个跨平台的lua游戏服务器开发框架,该框架采用多线程并发来处理消息,开发者只需要调用相应的接口函数并绑定相应的回调函数即可,在逻辑层表现为单线程的开发模式,使开发者易用,易调试,易维护,易扩展,同时拥有快速的响应能力。   框架使用面
参考链接:https://www.runoob.com/lua/lua-metatables.htmlhttps://www.jianshu.com/p/cb945e7073a3 元表是一个table,可以让我们改变table的行为,每个行为有对应的元方法例如,对table进行设置键值,查找键值,运算等,就会触发对应的元方法1--__index:table被访问时,如果找不到这
https://github.com/yuin/gopher-luahttps://github.com/yuin/gopher-lua Lua5.1ReferenceManual-contentshttp://www.lua.org/manual/5.1/ go中使用luapackagemainimport( lua"github.com/yuin/gopher-lua")funcmain(){ l:=lua.NewState() d
编译问题不要留到运行时才跑出来啊。早上9:00-中午3:00,6个小时,服了自己了。 写了一个测试,springboot+redis+lua执行到redisTemplate.execute(redisScript,idList)的时候一直报错,integer无法转换为string。我一直以为是lua脚本写错了,翻文档翻过来又翻过去,写法变了又变,还是解
        。。是字符串连接符,字典用=号连接,  注意fordoend都是连一起,  注意ifthen,  如果local在函数里,是可以访问,非local出了函数一样能用,  doend代码块也是一样,    注意点号表示,只能key是字符串,  注意括号不是必须
C语言与Lua之间的相互调用详解写一个C调用Lua的Demo编译运行C语言调用Lua编译问题总结正确的编译命令问题1:缺少-lm参数问题2:缺少-ldl参数​1、为什么会出现undefinedreferenceto‘xxxxx’错误?​2、-l参数和-L参数写一个C调用Lua的Demo编译运行add.c内容//你需要
1、动态输出打开E:\study\openresty\openresty-1.19.9.1-win64目录下的confginx.conf文件在server中增加一下代码 location/hello{ default_typetext/html; content_by_lua'ngx.say("<p>hello,world</p>")'; }运行后,效果如下图localhost
参见:lipp/lua-websockets:WebsocketsforLua.(github.com)github网址可能需手动转换lipp.github.com/lua-websockets/>github.com/lipp/lua-websocketswebsockets为底层的类似于TCP、UDP的socket(实现上基于更底层的socket),不同于上层的webserver服务端(Service)需并行地支持多
lua发送消息到rabbitmq,我们选择类库lua-resty-rabbitmqstomp 来完成这个任务。类库安装:进入nginx.conf中 lua_package_path 中对应的目录下的resty目录(没有则创建),执行:wget-chttps:/aw.githubusercontent.com/wingify/lua-resty-rabbitmqstomp/master/libes
1Lua介绍Lua是一门以其性能著称的脚本语言,被广泛应用在很多方面。Lua一般用于嵌入式应用,现在越来越多应用于游戏当中,魔兽世界,愤怒的小鸟都有用到。优势Lua极易嵌入到其他程序,可当做一种配置语言。提升应用性能,比如:游戏脚本,nginx,wireshark的脚本兼容性强,可以直接使用C