UVa1354,ACM/ICPC Tokyo 2005,Mobile Computing(天平难题)

1、题目

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、题意

给出房间的宽度 r r r s s s 个挂坠的重量 w i w_i wi。设计一个尽量宽(但宽度不能超过房间宽度 r r r)的天平,挂着所有挂坠。

天平由一些长度为1的木棍组成。木棍的每一端要么挂一个挂坠,要么挂另外一个木棍。如图7-9所示,设 n n n m m m 分别是两端挂的总重量,要让天平平衡,必须满足 n ∗ a = m ∗ b n*a=m*b na=mb
在这里插入图片描述
例如,如果有3个重量分别为1, 1, 2的挂坠,有3种平衡的天平,如图7-10所示。
在这里插入图片描述
挂坠的宽度忽略不计,且不同的子天平可以相互重叠。如图7-11所示,宽度为 ( 1 / 3 ) + 1 + ( 1 / 4 ) (1/3)+1+(1/4) (1/3)+1+(1/4)

输入第一行为数据组数。每组数据前两行为房间宽度 r r r 和挂坠数目 s s s 0 < r < 10 0<r<10 0<r<10 1 ≤ s ≤ 6 1≤s≤6 1s6)。以下 s s s 行每行为一个挂坠的重量 w i ( 1 ≤ w i ≤ 1000 ) w_i(1≤w_i≤1000) wi1wi1000。输入保证不存在天平的宽度恰好在 r − 1 0 − 5 r-10 ^{-5} r105 r + 1 0 − 5 r+10^{-5} r+105 之间(这样可以保证不会出现精度问题)。

对于每组数据,输出最优天平的宽度。如果无解,输出-1。你的输出和标准答案的绝对误差不应超过10-8

3、分析

如果把挂坠和木棍都作为结点,则一个天平对应一棵二叉树,如题目中给出的,挂坠为1, 1, 2的3个天平如图7-12所示。
在这里插入图片描述

对于一棵确定二叉树,可以计算出每个挂坠的确切位置,进而计算出整个天平的宽度,所以本题的核心任务是:枚举二叉树

如何枚举二叉树呢?最直观的方法是沿用回溯法框架,每次选择两个结点组成一棵子树,递归 s − 1 s-1 s1层即可。以4个挂坠1, 1, 2, 3为例,下面是解答树的一部分(每个结点的子树并没有全部画出),如图7-13所示。
在这里插入图片描述
上面的方法已经足够解决本题,但还有优化的余地,因为有些二叉树被枚举了多次(如图7-13中的两个粗框结点)。

推荐的枚举方法是:自顶向下构造,每次枚举左子树用到哪个子集,则右子树就是使用剩下的子集。

4、代码实现

// UVa1354 Mobile Computing
// Rujia Liu
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;struct Tree {double L, R; // distance from the root to the leftmost/rightmost pointTree():L(0),R(0) {}
};const int maxn = 6;int n, vis[1<<maxn];
double r, w[maxn], sum[1<<maxn];
vector<Tree> tree[1<<maxn];void dfs(int subset) {if(vis[subset]) return;vis[subset] = true;bool have_children = false;for(int left = (subset-1)&subset; left; left = (left-1)&subset) {have_children = true;int right = subset^left;double d1 = sum[right] / sum[subset];double d2 = sum[left] / sum[subset];dfs(left); dfs(right);for(int i = 0; i < tree[left].size(); i++)for(int j = 0; j < tree[right].size(); j++) {Tree t;t.L = max(tree[left][i].L + d1, tree[right][j].L - d2);t.R = max(tree[right][j].R + d2, tree[left][i].R - d1);if(t.L + t.R < r) tree[subset].push_back(t);}}if(!have_children) tree[subset].push_back(Tree());
}int main() {int T;scanf("%d", &T);while(T--) {scanf("%lf%d", &r, &n);for(int i = 0; i < n; i++) scanf("%lf", &w[i]);for(int i = 0; i < (1<<n); i++) {sum[i] = 0;tree[i].clear();for(int j = 0; j < n; j++)if(i & (1<<j)) sum[i] += w[j];}int root = (1<<n)-1;memset(vis, 0, sizeof(vis));dfs(root);double ans = -1;for(int i = 0; i < tree[root].size(); i++)ans = max(ans, tree[root][i].L + tree[root][i].R);printf("%.10lf\n", ans);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/151080.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【云原生】portainer管理多个独立docker服务器

目录 一、portainer简介 二、安装Portainer 1.1 内网环境下&#xff1a; 1.1.1 方式1&#xff1a;命令行运行 1.1.2 方式2&#xff1a;通过compose-file来启动 2.1 配置本地主机&#xff08;node-1&#xff09; 3.1 配置其他主机&#xff08;被node-1管理的节点服务器&…

MobPush厂商通道回执配置指南(Vivo,荣耀)

MobPush作为一款好用、可靠的智能推送开发者工具&#xff0c;为APP开发者提供了推送后用户行为的全链路数据分析&#xff0c;从而开发者可以更好地了解用户行为&#xff0c;优化推送策略&#xff0c;提高消息送达率&#xff0c;从而提升用户体验。 但这需要通过在后台配置厂商…

私有化部署企业IM即时通讯app,群聊多样化管控

随着企业内部沟通和协作的重要性不断增长&#xff0c;私有化部署企业即时通讯&#xff08;IM&#xff09;app成为了企业保护内部信息安全的一种重要手段。在这个领域&#xff0c;安全专属的移动数字化平台WorkPlus&#xff0c;支持私有化部署&#xff0c;涵盖即时通讯和办公应用…

Leo赠书活动-03期 【ChatGPT 驱动软件开发:AI 在软件研发全流程中的革新与实践 】

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; 赠书活动专栏 ✨特色专栏&#xff1a;…

C语言数据结构之数据结构入门

目录 数据结构介绍 数据结构发展史 何为算法 数据结构基础 基本概念和术语 四大逻辑结构&#xff08;Logic Structure&#xff09; 数据类型 理解复杂度概念 时间空间复杂度定义 度量时间复杂度的方法 程序运行时的内存与地址 编程预备 数据结构介绍 数据结构发展…

面试总结之消息中间件

RabbitMQ的消息如何实现路由 RabbitMQ是一个基于AMQP协议实现的分布式消息中间件&#xff0c;AMQP具体的工作机制是生产者将消息发送到RabbitMQ Broker上的Exchange交换机上&#xff0c;Exchange交换机将收到的消息根据路由规则发给绑定的队列&#xff08;Queue&#xff09;&am…

Centos7 安装和配置 Redis 5 教程

在Centos上安装Redis 5&#xff0c;如果是 Centos8&#xff0c;那么 yum 仓库中默认的 redis 版本就是 5&#xff0c;直接 yum install 即可。但如果是 Centos7&#xff0c;yum 仓库中默认的 redis 版本是 3 系列&#xff0c;比较老&#xff1a; 通过 yum list | grep redis 命…

并查集(畅通工程)

并查集就是不相交的集合 有两个常见操作&#xff1a; 1.合并 2.查询某元素属于什么集合 法一&#xff1a; 代码如下&#xff1a; find 目的找到元素的老大 &#xff08;链表遍历逐层向上找&#xff09; merge 合并集合&#xff08;实质改变集合老大&#xff0c;链表性质&…

降级熔断:如何屏蔽非核心系统故障的影响?

目录 前言 一、熔断是什么&#xff1f; 二、服务降级 三、雪崩是如何发生的 四、hystrix使用 五、降级机制要如何做 总结 前言 在“双十一”的巨大流量中&#xff0c;商品促销过程中出现了几次短暂的服务不可用&#xff0c;这给部分用户造成了不好的使用体验。事后&…

大数据架构设计理论与实践

大数据架构设计理论与实践 大数据处理系统概述 传统数据处理系统存在的问题 大数据处理系统面临的挑战 大数据处理系统的属性/特征 典型的大数据架构 Lambda架构 Lambda定义 优缺点 应用场景 Lambda的体系结构( Batch Layer (批处理层)、Speed Layer (加速层)、Serving Lay…

(el-Table)操作(不使用 ts):Element-plus 中 Table 多选框的样式等的调整

Ⅰ、Element-plus 提供的 Table 表格组件与想要目标情况的对比&#xff1a; 1、Element-plus 提供 Table 组件情况&#xff1a; 其一、Element-ui 自提供的 Table 代码情况为(示例的代码)&#xff1a; // Element-plus 自提供的代码&#xff1a; // 此时是使用了 ts 语言环境…

轮转数组(Java)

大家好我是苏麟 , 这篇文章是凑数的 ... 轮转数组 描述 : 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 题目 : 牛客 NC110 旋转数组: 这里牛客给出了数组长度我们直接用就可以了 . LeetCode 189.轮转数组 : 189. 轮…