题意:

     给出房间的宽度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)的更多相关文章

  1. LA3403 天平难题

    题意:      给出房间的宽度r和每个吊坠的重量wi,设计一个尽量宽但宽度不能超过房间宽度的天平,挂着所有挂坠,每个天平的一段要么挂这一个吊坠,要么挂着另一个天平,每个天平的总长度是1,细节我给出题 ...

  2. uva1354 天平难题 【位枚举子集】||【huffman树】

    题目链接:https://vjudge.net/contest/210334#problem/G 转载于:https://blog.csdn.net/todobe/article/details/54 ...

  3. UVa 1354 天平难题

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. UVa 1354 天平难题 (枚举二叉树)

    题意: 分析: 其实刚看到这题的时候觉得很难, 以至于结束了第七章然后去做了一遍第六章树的部分.现在再做这题觉得思路并不是太难,因为总共就只有六个结点,那么只要枚举二叉树然后算出天平然后再从叶子往上推 ...

  5. UVa 1354 天平难题 Mobile Computing

    整个题考虑起来 最主要要计算的状态 是树的状态 于是要计算出所有可能挂坠可能组成的树的所有形态 tree 用于保存这些状态 考虑不要重复计算,有一个vis 数组 预处理可以先计算出一棵树的重量,简化计 ...

  6. 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 ...

  7. 【BZOJ】1673: [Usaco2005 Dec]Scales 天平(dfs背包)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1673 bzoj翻译过来的c<=230不忍吐槽......................... ...

  8. UVA - 12166 Equilibrium Mobile (修改天平)(dfs字符串表示的二叉树)

    题意:问使天平平衡需要改动的最少的叶子结点重量的个数. 分析:天平达到平衡总会有个重量,这个重量可以由某个叶子结点的重量和深度直接决定. 如下例子: 假设根结点深度为0,结点6深度为1,若以该结点为基 ...

  9. UVa 12118 检查员的难题(dfs+欧拉回路)

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

随机推荐

  1. HDOJ-6685(暴力+思维)

    Rikka With Coin HDOJ-6685 主要的思想如下: 首先10元的硬币最多只会用一个,如果用了两个,直接替换成一个10元.一个20元一定不亏. 20元的硬币最多只会用三个,如果用了四个 ...

  2. 洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树

    洛谷P3285 [SCOI2014]方伯伯的OJ 动态开点平衡树 题目描述 方伯伯正在做他的 \(Oj\) .现在他在处理 \(Oj\) 上的用户排名问题. \(Oj\) 上注册了 \(n\) 个用户 ...

  3. Hi3559AV100 NNIE开发(4)mobilefacenet.cfg参数配置挖坑解决与SVP_NNIE_Cnn实现分析

    前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefa ...

  4. jQuery学习笔记(1) 初识jQuery

    目录 目录 引用 注意 HelloWorldHelloWorld! jQueryjQuery对象和DOMDOM对象的相互转换 冲突的解决 引用 本地文件引用: <script src=" ...

  5. linux安装mysql8.0

    linux 上安装mysql8.0 mysql版本8.0.16 MySQL Community 操作系统centos7 准备工作: mysql8.0 rpm文件 安装步骤: 1. 下载mysql的re ...

  6. Xshell(远程)连接不上linux服务器(防火墙介绍)

    一.原因 远程(ssh)连接不上linux服务器的大多数原因都是因为本地服务器的防火墙策略导致的,因此我们想ssh远程能够连接上服务器,有两种方法: 修改防火墙策略 关闭防火墙 二.防火墙服务介绍 1 ...

  7. 七种join的书写规范

    在mysql中的两表进行连接时,总共有7种连接情况,具体可见下图 由图的从左到右的顺序 图1.左连接(left join):返回左表中的所有记录和右表中的连接字符字段相等的记录,若右表没有匹配值则补N ...

  8. Lambda 表达式(使用前提、“类型推断”、作用、优缺点、Lambda还能省略的情况)

    Lambda 表达式(使用前提."类型推断".作用.优缺点.Lambda还能省略的情况) 1.Lambda使用前提: (1)使用Lambda必须有接口,且接口只有一个抽象方法(即函 ...

  9. PTA 数组元素的区间删除

    6-6 数组元素的区间删除 (20 分)   给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素.删除后表中剩余元素保持顺序存储,并且相对位置不能改变. 函数接口定义: ...

  10. 攻防世界 reverse android-app-100

     android-app-100  suctf-2016 jeb启动,找到点击事件: 验证流程: 输入作为参数 --> processObjectArrayFromNative 得到一返回值(r ...