zoukankan      html  css  js  c++  java
  • POJ 2057 The Lost House (经典树形dp)

      不错的题,做了两次。两次感觉不一样,第一次那叫一个费劲啊。。。看了一天的解题报告,才大概理解怎么回事,这次做完好好写写总结吧。

    开始想到的状态有sum[i]表示以i为根的子树走遍所有的字节点的值,leaves[i]表示以i为跟的子树的叶子节点数。显然是错误的。。。好多状态表示不出来。

    后来有考虑分回到i节点和不回到i节点这两种状态。但还是设计不出来,最不能确定的就是一个顺序问题。无奈翻了一下以前看的资料。发现一个没有想到的贪心方法。。。。

     success[u]表示u为根的子树上,成功找到房子的步数和

     fail[u]表示u为根的子树上,找不到房子的步数和

     leaves[u]表示u为根的子树上,叶子节点数

     如果u节点有worm,则fail[u] = 0;

       

     success[u] += (fail[u] + 1)*leave[v] + success[v];  //+1是因为要走到v子树

     fail[u] += (fail[v] + 2);    //+2表示走到又回来了。

    表示u->v上,前边与u相连的所有子树都没有成功,到v子树成功找到房子的步数。

    子所以要 (fail[u] + 2)*leave[v] ....这个画一下图就知道了。咳咳

     现在关键要解决的是按怎么样的顺序遍历u的所有字节点使得得到的success[u]最小。

    显然,当(fail[u] + 1) *leave[v]越小,success[u]越小。设i,j为u的两颗子树, leave[i]越大fail[i]越小,越应该往前排(贪心),这样能保证 (fail[u] + 1)*leave[v]取的值最小

    变形一下 leave[i]/fail[i] > leave[j]/fail[j];也就是说按照 leave[i]/fail[i]从大到小排序。 

    bool cmp(const int u, const int v) {
      return leaves[u]*(fail[v] + 2) > leaves[v]*(fail[u] + 2);
    }

    可以先dfs遍历完u的所有子树,然后再确定顺序进行计算(注意节点为叶节点的情况。success[i] = fail[i] = 0, leaves[i] = 1)

      

      

      

       

        

  • 相关阅读:
    Cocos2d-x 3.2编译生成Android程序出错Error running command, return code: 2的解决方法
    利用Theme自定义Activity进入退出动画
    Activity的四种launchMode
    android中设置控件获得焦点
    android 反编译 for mac
    android中libs目录下armeabi和armeabi-v7a的区别
    解决Sublime Text 3中文显示乱码(tab中文方块)问题,sublime tab乱码
    mysql教程
    Failed to load c++ bson extension, using pure JS version
    mongodb导出数据
  • 原文地址:https://www.cnblogs.com/vongang/p/2647703.html
Copyright © 2011-2022 走看看