UVa 1354 天平难题 枚举二叉树
题意:给出房间宽度 r 和 s 个挂坠的重量 wi,设计一个尽量宽的天平,挂着所有挂坠。天平由一些长度为 1 的木棍组成,木棍的每一端要么挂一个挂坠,要么挂另外一个木棍。
这题卡了很久,看了很多大神的代码,终于把细节都搞懂了。
将挂坠所有可能的集合的重量算出来,再用二进制的方式枚举子集(左子树)和补集(右子树)构成二叉树,算出左右的宽度。
代码:
#include <iostream> #include <cstring> #include <vector> using namespace std;const int MAX = 6;struct Tree{double L, R; //树的左边和右边的长度Tree():L(0), R(0){} };double width, w[MAX], sum[1<<MAX]; int vis[1<<MAX]; vector<Tree> tree[1<<MAX]; //枚举出来的结点可以组合成多个树void dfs(int subset); //枚举二叉树int main(){freopen("input.txt", "r", stdin);int T;cin >> T;while(T--){int s;scanf("%lf%d", &width, &s);for(int i=0; i<s; i++){scanf("%lf", &w[i]);}//初始化 memset(sum, 0, sizeof(sum));for(int i=1; i<(1<<s); i++){tree[i].clear(); //清空树int k = 1;for(int j=0; j<s; j++){ //算出当前集合所有结点的重量和if(k & i){sum[i] += w[j];}k = (k << 1);} }//进行枚举int root = (1<<s) - 1;memset(vis, 0, sizeof(vis));dfs(root);//得到最大的答案double ans = -1;for(int i=0; i<tree[root].size(); i++){ans = max(tree[root][i].L + tree[root][i].R, ans);} printf("%.10lf\n", ans);}} void dfs(int subset){if(vis[subset])return;vis[subset] = 1;bool hasChild = false;for(int left = ((subset-1) & subset); left > 0; left = ((left-1) & subset)){ //枚举集合 hasChild = true;int right = subset ^ left; //left 的补集double l = sum[right] / sum[subset]; //左臂长度double r = 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 + l, tree[right][j].L - r);t.R = max(tree[right][j].R + r, tree[left][i].R - l);if(t.L + t.R < width){ //如果满足条件,枚举结果加一 tree[subset].push_back(t); }}}}if(!hasChild){ //叶子结点的左右臂为零 tree[subset].push_back(Tree());}}
转载于:https://www.cnblogs.com/lighter-blog/p/7216349.html
UVa 1354 天平难题 枚举二叉树相关推荐
- UVA1354天平难题 枚举二叉树
题意:给出房间宽度r和s个挂坠的重量wi.设计一个尽量宽(但宽度不能超过房间宽度r)的天平,挂着所有挂坠.天平由一些长度为1的木棍组成.木棍的每一端要么挂一个挂坠,要么挂另一个木棍,设n和m分别是两端 ...
- LA3403天平难题(4个DFS)
题意: 给出房间的宽度r和每个吊坠的重量wi,设计一个尽量宽但宽度不能超过房间宽度的天平,挂着所有挂坠,每个天平的一段要么挂这一个吊坠,要么挂着另一个天平,每个天平的总长度是1,细节我给出题 ...
- LA3403 天平难题
题意: 给出房间的宽度r和每个吊坠的重量wi,设计一个尽量宽但宽度不能超过房间宽度的天平,挂着所有挂坠,每个天平的一段要么挂这一个吊坠,要么挂着另一个天平,每个天平的总长度是1,细节我给出题 ...
- UVA 1354 Mobile Computing
题意: 给出房间的宽度r和s个挂坠的重量wi.设计一个尽量宽的天平(不能超过房间的宽度),挂着所有的挂坠.天平由长度为l的木棍组成,天平的一端不是挂坠就是另一个天平.必须满足n*a=m*b(l=a+b ...
- Uva 201 Squares (暴力 + 枚举)
[题意] 给出 n*n 的 点 H 横向 V 纵向 (注意) V 想 I,j 相反 问 边 为1 ,2 , 3 .... n 的 正方向有几个 [思路] n 很小 直接暴力 枚举 枚举 ...
- UVA 11134 Fabled Rook 枚举 multiset加速
题意说的是给出一个长度为n的国际象棋的棋盘,然后给出n个车的可以放置的范围,范围是一个矩形,用左上和右下两对数来描述,问是否存在方式使得每个车都放在他自己的范围里面且相互不冲突 这里x方向和y方向是不 ...
- UVa 140 Bandwidth【枚举排列】
题意:给出n个节点的图,和一个节点的排列,定义节点i的带宽b[i]为i和其相邻节点在排列中的最远的距离,所有的b[i]的最大值为这个图的带宽,给一个图,求出带宽最小的节点排列 看的紫书,紫书上说得很详 ...
- UVa 839 天平
分析:这是DFS又一个经典题目,符合DFS的理念一路搜到底,再回头. 主要难度在于递归边界的书写上.(这个题的类型非常重要) 代码如下: #include <iostream> #incl ...
- AcWing479.加分二叉树(区间DP)题解
加分二叉树 题目传送门 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号. 每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...
最新文章
- numpy.ravel() vs numpy.flatten()
- 怎么解决深入学习PHP的瓶颈
- 取模除法(逆元)(费马小定理)(线性求逆元)
- php把表单转为json保存,javascript – 使用jquery将表单数据保存到本地json文件中
- iText报表Java_(例)Java生成PDF报表 iText
- Docker 从入门到掉坑
- 补天五星计划范围更新,还有单个漏洞额外10000元现金奖励?!
- ElasticSearch 插件开发
- 信息技术是一把双刃剑,如何掌控好这柄剑?
- jumpserver开源堡垒机部署安装
- Linux下防止用户查看他人的进程-hidepid
- 福利卡巴斯基一年免费以及一些使用软件
- 什么是TTL?标准USB接口是TTL吗?RS232、RS422、RS485的区别?
- python闰月计算_Python实例讲解 -- 获取本地时间日期(日期计算)
- 开发人员如何在面试中介绍自己的项目经历
- Java 并发编程艺术 读书笔记
- AD那些事 切割板子形状,线的弧度转换
- 全国大学生软件测试大赛Web应用测试(五)Jmeter性能测试环境配置
- 以太网UDP数据协议
- 电力系统风力发电机组测控专用隔离变送器
热门文章
- java数组的调用_java中数组的应用及方法
- Tomcat开发Web项目基本结构
- 小学生计算机舞蹈,最近“泼水成画”很火?舞蹈生VS体育生,看到计算机:你是来添乱的?...
- 『设计模式』 又谈麦当劳的食品--组合模式(Composite)
- Markdown中希腊字母与代码对应表
- HDU-1857 畅通工程再续
- 数据结构-“栈”的基本操作
- 如何在64位Ubuntu16.04下安装java开发环境
- 如何使用eclipse进行嵌入式Linux的开发
- 升级到BigSur无法使用git和brew解决办法