LA3403天平难题(4个DFS)
题意:
给出房间的宽度r和每个吊坠的重量wi,设计一个尽量宽但宽度不能超过房间宽度的天平,挂着所有挂坠,每个天平的一段要么挂这一个吊坠,要么挂着另一个天平,每个天平的总长度是1,细节我给出题目中的几个图来方便理解:
思路:
敲了将近两个小时,数据比较小,也就是说只要找到解决方法,一般就可以直接AC了,首先我们可以搜索枚举天平的状态,就是总的天平的框架的样子,也就是二叉树的样子,这个地方卡了一会才想出来,我们可以直接枚举当天天平上有的点,每一步搜索是在当前天平上已有的点的叶子节点中两种决策,要么增加一个天平,要么不增加,在别的叶子节点上增加天平,总之当前这一步要在一个叶子节点上增加天平,(想想我们画二叉树的时候是不是这样画的),而且每增加一个天平就会在二叉树上增加一个挂坠的数量,一直增加到测试数据给的吊坠的数量,对于每一个枚举得到的二叉树,我们可以知道他一定是n个叶子节点的二叉树,然后我们用一个全排列(也可以写深搜,用全排列是为了不让代码太多,太乱)给这个叶子附上对应的重量,赋完重量之后我们可以再用深搜来给每个非叶子节点到他做儿子和有儿子的距离求出来,这个比较简单(不会可以直接看下面代码),求完距离之后可以用深搜遍历没一条路径,树根的坐标是0,然后往左就-,往右就+得到一个最大和最小的坐标,然后根据坐标差来更新最优值,这个题目我写了三个深搜,一个全排列AC的,感觉实现的有点麻烦,但不知道有没有更省事的,目前百度不到,还有就是有一个比较坑人的地方就是当吊坠只有一个的时候直接输出0,不是-1。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define N 3000
using namespace std;
typedef struct
{
double ll ,rr ,ww;
int mk;
}NODE;
NODE node[N];
int Now[N] ,n ,nn;
double num[10] ,r ,Ans;
double minn ,maxx;
double DFSlr(int now)
{
if(node[now].mk) return node[now].ww;
double lsum = DFSlr(now * 2);
double rsum = DFSlr(now * 2 + 1);
node[now].ll = rsum / (lsum + rsum);
node[now].rr = lsum / (lsum + rsum);
return lsum + rsum;
}
void DFSmm(double v ,int now)
{
if(node[now].mk)
{
if(minn > v) minn = v;
if(maxx < v) maxx = v;
return;
}
DFSmm(v - node[now].ll ,now * 2);
DFSmm(v + node[now].rr ,now * 2 + 1);
}
void DFS(int sw ,int sumnode)
{
if(sw == n)
{
int tmpyz[10] ,nowid = 0;
for(int i = 1 ;i <= sumnode ;i ++)
if(node[Now[i]].mk) tmpyz[++nowid] = Now[i];
for(int i = 1 ;i <= nn+1 ;i ++)
{
for(int j = 1 ;j <= n ;j ++)
node[tmpyz[j]].ww = num[j];
DFSlr(1);
maxx = -100000 ,minn = 100000;
DFSmm(0 ,1);
if(maxx - minn <= r)
{
if(Ans < maxx - minn)
Ans = maxx - minn;
}
next_permutation(num + 1 ,num + n + 1);
}
return;
}
for(int i = 1 ;i <= sumnode ;i ++)
{
if(node[Now[i]].mk)
{
node[Now[i]].mk = 0;
node[Now[i]*2].mk = 1;
node[Now[i]*2+1].mk = 1;
Now[sumnode+1] = Now[i]*2;
Now[sumnode+2] = Now[i]*2+1;
DFS(sw + 1 ,sumnode + 2);
node[Now[i]].mk = 1;
node[Now[i]*2].mk = 0;
node[Now[i]*2+1].mk = 0;
}
}
}
int main ()
{
int t ,i;
scanf("%d" ,&t);
while(t--)
{
scanf("%lf" ,&r);
scanf("%d" ,&n);
for(nn = i = 1 ;i <= n ;i ++)
{
scanf("%lf" ,&num[i]);
nn *= i;
}
if(n == 1)
{
printf("0\n");
continue;
}
memset(node ,0 ,sizeof(node));
Now[1] = 1 ,Ans = -1;
node[1].mk = 1;
DFS(1 ,1);
printf("%.16lf\n" ,Ans);
}
return 0;
}
LA3403天平难题(4个DFS)的更多相关文章
- LA3403 天平难题
题意: 给出房间的宽度r和每个吊坠的重量wi,设计一个尽量宽但宽度不能超过房间宽度的天平,挂着所有挂坠,每个天平的一段要么挂这一个吊坠,要么挂着另一个天平,每个天平的总长度是1,细节我给出题 ...
- uva1354 天平难题 【位枚举子集】||【huffman树】
题目链接:https://vjudge.net/contest/210334#problem/G 转载于:https://blog.csdn.net/todobe/article/details/54 ...
- UVa 1354 天平难题
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVa 1354 天平难题 (枚举二叉树)
题意: 分析: 其实刚看到这题的时候觉得很难, 以至于结束了第七章然后去做了一遍第六章树的部分.现在再做这题觉得思路并不是太难,因为总共就只有六个结点,那么只要枚举二叉树然后算出天平然后再从叶子往上推 ...
- UVa 1354 天平难题 Mobile Computing
整个题考虑起来 最主要要计算的状态 是树的状态 于是要计算出所有可能挂坠可能组成的树的所有形态 tree 用于保存这些状态 考虑不要重复计算,有一个vis 数组 预处理可以先计算出一棵树的重量,简化计 ...
- Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs
C. Vanya and Scales Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/552/p ...
- 【BZOJ】1673: [Usaco2005 Dec]Scales 天平(dfs背包)
http://www.lydsy.com/JudgeOnline/problem.php?id=1673 bzoj翻译过来的c<=230不忍吐槽......................... ...
- UVA - 12166 Equilibrium Mobile (修改天平)(dfs字符串表示的二叉树)
题意:问使天平平衡需要改动的最少的叶子结点重量的个数. 分析:天平达到平衡总会有个重量,这个重量可以由某个叶子结点的重量和深度直接决定. 如下例子: 假设根结点深度为0,结点6深度为1,若以该结点为基 ...
- UVa 12118 检查员的难题(dfs+欧拉回路)
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
随机推荐
- crontab任务重复执行?不执行?不按照配置执行?大概率是配置出错了!!!
在使用crontab配置定时任务是,容易大意出错的配置记录,有温度的文章分享,有态度的日常记录- 一.情景1 设置每天凌晨执行某一任务,结果发现凌晨0点没分钟都执行了一次,我的天!!! 1.分析原因可 ...
- Java 虚拟机详解
深入理解JVM 1 Java技术与Java虚拟机 说起Java,人们首先想到的是Java编程语言,然而事实上,Java是一种技术,它由四方面组成: Java编程语言.Java类文件格式.Java虚 ...
- Tomcat源码学习 - 环境搭建
一. 源码下载 PS: 多图预警 在开始阅读源码之前,我们需要先构建一个环境,这样才能便于我们对源码进行调试,具体源码我们可以到官网进行下载(这里我以8.5.63版本为例). 二. 项目导入 下载并解 ...
- LiberOJ #124. 除数函数求和 【整除分块】
一.题目 #124. 除数函数求和 二.分析 比较好的一题,首先我们要对题目和样例进行分析,明白题目的意思. 由于对于每一个$d$,它所能整除的数其实都是定的,且数量是$ \lfloor \frac{ ...
- 关于python浮点数精度问题计算误差的原因分析
在python中使用浮点数运算可能会出现如下问题 a = 0.1+0.2print(a) 输出的结果是 0.30000000000000004 原因如下: 出现上面的情况,主要还是因浮点数在计算机中实 ...
- 热门跨平台方案对比:WEEX、React Native、Flutter和PWA
本文主要对WEEX.React Native.Flutter和PWA几大热门跨平台方案进行简单的介绍和对比.内容选自<WEEX跨平台开发实战> (WEEX项目负责人力荐,从入门到实战,教你 ...
- Gevent高并发网络库精解
进程 线程 协程 异步 并发编程(不是并行)目前有四种方式:多进程.多线程.协程和异步. 多进程编程在python中有类似C的os.fork,更高层封装的有multiprocessing标准库 多线程 ...
- 对接快递100&聚水潭API
对接快递100&聚水潭API 入我相思门,知我相思苦. 简介:对接第三方平台快递100&聚水潭API的简要总结. 1.感悟 个人感觉快递100的API更友好一些,比如有SDK可以调用: ...
- python基础之基本数据类型与基本运算符
一.基本数据类型 1.整数类型 作用:描述年龄.等级,电话号码等数据类型 age = 18 phone_number = 13572839204 2.浮点型 作用:描述薪资.身高等带小数的类型 hei ...
- 如何从 dump 文件中提取出 C# 源代码?
一:背景 相信有很多朋友在遇到应用程序各种奇葩问题后,拿下来一个dump文件,辛辛苦苦分析了大半天,终于在某一个线程的调用栈上找到了一个可疑的方法,但 windbg 常常是以 汇编 的方式显示方法代码 ...