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)

      

      

      

       

        

  • 相关阅读:
    matplot 代码实例2
    sklearn 线性模型使用入门
    python 之 决策树分类算法
    Leetcode 之Simplify Path @ python
    协同过滤CF算法之入门
    linux 下 rpc python 实例之使用XML-RPC进行远程文件共享
    Linux rpc 编程最简单实例
    Opencv 入门学习之图片人脸识别
    Django1.7开发博客
    Opencv 入门学习1
  • 原文地址:https://www.cnblogs.com/vongang/p/2647703.html
Copyright © 2011-2022 走看看