题意:
     给出房间的宽度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天平难题 枚举二叉树

    题意:给出房间宽度r和s个挂坠的重量wi.设计一个尽量宽(但宽度不能超过房间宽度r)的天平,挂着所有挂坠.天平由一些长度为1的木棍组成.木棍的每一端要么挂一个挂坠,要么挂另一个木棍,设n和m分别是两端 ...

  3. UVa 1354 天平难题 枚举二叉树

    题意:给出房间宽度 r 和 s 个挂坠的重量 wi,设计一个尽量宽的天平,挂着所有挂坠.天平由一些长度为 1 的木棍组成,木棍的每一端要么挂一个挂坠,要么挂另外一个木棍. 这题卡了很久,看了很多大神的 ...

  4. UVa12166 Equilibrium Mobile修改天平(二叉树+dfs)

    题目大意:给定一个深度不超过16的二叉树,代表一个天平,问至少修改多少个秤砣,才能使天平平衡. 题目意思很简单,就是找一个可以使整个天平修改次数最少的点,一个点可以确定整个天平,开始我就用的这个思路, ...

  5. 数独小项目开篇:DFS解决数独难题

    数独小项目开篇:DFS解决数独难题 前言 DFS解决数独问题思路 代码实现细节 样例测试 总结 Reference 前言   这周小刀是挺忙的,周末加班,哎,谁不是996呢?(打工魂燃烧吧~   这次 ...

  6. DFS:C 小Y的难题(1)

    解题心得: 1.在明确使用DFS之后一定要找到递归函数的出口.方向,以及递归的点(在某个情况下开始递归)(void 也可以return,但是没有返回值).递归时也要有递归的方向,最后都能够达到递归的出 ...

  7. (二叉树DFS)天平UVa 839

    题目 输入一个树状天平,根据力矩相等原则判断是否平衡.如图6-5所示,所谓力矩相等,就是WlDl=WrDr,其中Wl和Wr分别为左右两边砝码的重量,D为距离.采用递归(先序)方式输入:每个天平的格式为 ...

  8. bzoj 1673: [Usaco2005 Dec]Scales 天平(DFS)

    1673: [Usaco2005 Dec]Scales 天平 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 695  Solved: 253 [Subm ...

  9. BZOJ 1673 [Usaco2005 Dec]Scales 天平:dfs 启发式搜索 A*搜索

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1673 题意: 有n个砝码(n <= 1000),重量为w[i]. 你要从中选择一些砝 ...

最新文章

  1. Shell基础命令之echo
  2. Cell子刊:中科院遗传发育所周俭民组发现特异靶向病原菌致病力的植物天然产物并阐明作用机制
  3. DPM2007轻松恢复Exchange邮件,DPM2007系列之三
  4. 英特尔CPU机密数据大量泄露:芯片后门实锤,下一代CPU原理图曝光
  5. 日常生活小技巧 -- UltraEdit复制16进制数据
  6. 段错误 php,php扩展出现段错误怎么办
  7. TensorFlow——本地加载fashion-mnist数据集
  8. js方式调用php_js如何调用php函数
  9. 线程打印状态_Java线程状态的转换
  10. windows安装TortoiseGit
  11. Spring Data —— 完全统一的API?
  12. python 数据类型 之 tuple 元组
  13. 每日英语:How to say No to other people
  14. Android Studio 第五十五期 - Studio3.0升级到gradle3.0.0后API失效方案
  15. 基于豆瓣和妹子的api用React Native写的demo
  16. Android 状态栏背景颜色修改与状态栏字体颜色修改
  17. php的表达爱意的一句代码,表达爱意的诗句(精选50句)
  18. dd软件linux,dd工具
  19. GitHub 标星 2.9w+,我发现了一个宝藏项目,作为编程新手有福了!
  20. 《惢客创业日记》2019.11.28(周四)近者悦,远者来

热门文章

  1. 《Groovy官方指南》翻译邀请
  2. Spring的静态代理和动态代理
  3. Spring的依赖注入和管理Bean
  4. Java HashMap遍历的两种方式
  5. 大学生学业指导类书目
  6. T^TOJ - 1251 - 。◕‿◕。TMD - 欧拉函数 - 质因数分解
  7. UVA1103分区涂色+vc使用注意事项
  8. MyEclipse 15 集成SVN
  9. 推荐一本书《网络机器人java编程指南》
  10. GARFIELD@05-04-2005