博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2057 The Lost House (经典树形dp)
阅读量:6281 次
发布时间:2019-06-22

本文共 940 字,大约阅读时间需要 3 分钟。

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

开始想到的状态有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)

  

  

  

   

 

 

 

    

转载地址:http://hwxva.baihongyu.com/

你可能感兴趣的文章
spring boot集成mongodb最简单版
查看>>
DELL EqualLogic PS存储数据恢复全过程整理
查看>>
《Node.js入门经典》一2.3 安装模块
查看>>
《Java 开发从入门到精通》—— 2.5 技术解惑
查看>>
Linux 性能诊断 perf使用指南
查看>>
实操分享:看看小白我如何第一次搭建阿里云windows服务器(Tomcat+Mysql)
查看>>
Sphinx 配置文件说明
查看>>
数据结构实践——顺序表应用
查看>>
python2.7 之centos7 安装 pip, Scrapy
查看>>
机智云开源框架初始化顺序
查看>>
Spark修炼之道(进阶篇)——Spark入门到精通:第五节 Spark编程模型(二)
查看>>
一线架构师实践指南:云时代下双活零切换的七大关键点
查看>>
ART世界探险(19) - 优化编译器的编译流程
查看>>
玩转Edas应用部署
查看>>
music-音符与常用记号
查看>>
sql操作命令
查看>>
zip 数据压缩
查看>>
Python爬虫学习系列教程
查看>>
【数据库优化专题】MySQL视图优化(二)
查看>>
【转载】每个程序员都应该学习使用Python或Ruby
查看>>