消防局的建立
本题地址: http://www.luogu.org/problem/show?pid=2279

题目描述

2020年,人类在火星上建立了一个庞大的基地群,总共有n个基地。起初为了节约材料,人类只修建了n-1条道路来连接这些基地,并且每两个基地都能够通过道路到达,所以所有的基地形成了一个巨大的树状结构。如果基地A到基地B至少要经过d条道路的话,我们称基地A到基地B的距离为d。
由于火星上非常干燥,经常引发火灾,人类决定在火星上修建若干个消防局。消防局只能修建在基地里,每个消防局有能力扑灭与它距离不超过2的基地的火灾。
你的任务是计算至少要修建多少个消防局才能够确保火星上所有的基地在发生火灾时,消防队有能力及时扑灭火灾。

输入输出格式

输入格式:
输入文件名为input.txt。
输入文件的第一行为n (n<=1000),表示火星上基地的数目。接下来的n-1行每行有一个正整数,其中文件第i行的正整数为a[i],表示从编号为i的基地到编号为a[i]的基地之间有一条道路,为了更加简洁的描述树状结构的基地群,有a[i]< i。

输出格式:
输出文件名为output.txt
输出文件仅有一个正整数,表示至少要设立多少个消防局才有能力及时扑灭任何基地发生的火灾。

输入输出样例
输入样例#1:
6
1
2
3
4
5
输出样例#1:
2

题解

这是一道蛋疼的树形DP,树形DP一般状态表示比较复杂;在题解帮助下过掉;
%大神Crazyxx http://202.101.104.45:8888/space/show?uid=6076
状态:
dp[i][0]:选自己
dp[i][1]:选了至少一个儿子
dp[i][2]:选了至少一个孙子
———————————–这三种是覆盖了自己的
dp[i][3]: 儿子孙子全部覆盖
dp[i][4]:孙子全部覆盖
———————————–这两种并没有覆盖自己
建议画一棵深度为3的完全二叉树直观观察状态 否则转移方程比较难懂

初始转移方程:
dp[i][0] = 1+Σmin(dp[j][0…4]);
要使选了根节点之后合法(整棵子树包括根节点被覆盖)必须使儿子的孙子全部覆盖 0~4状态满足
dp[i][1] = min( dp[k][0] + Σ(j != k)min(dp[j][0…3]) );
要使选了一个儿子之后合法 由于儿子只可以覆盖到兄弟 所以孙子一定要全部被覆盖 即儿子的儿子一定覆盖 0~3满足
dp[i][2] = min( dp[k][1] + Σ(j != k)min(dp[j][0…2]) );
使选了一个孙子之后合法 由于孙子最多只能覆盖到当前节点 所以儿子一定全部覆盖 即所有儿子本身要被覆盖 0~2满足
dp[i][3] = Σdp[j][0…2];
要使儿子及孙子全部被覆盖 即儿子本身要被覆盖 0~2满足
dp[i][4] = Σdp[j][0…3];
要使孙子全部被覆盖 即儿子的儿子要全部被覆盖 0~3满足
::注意每种状态由儿子转移过来所以根的情况 要转化成对于儿子来说的情况

然后改进状态 因为每种转移方程至少有三种可能最后取其中较小的 故时间效率较低 令dp[i][k]表示min(dp[i][0],dp[i][1]….dp[i][k])且k>=2 因为上述转移方程最少都是0~2状态
那么转移方程就大幅度化简了:
dp[i][0] = 1+Σdp[j][4];
直接由上面变形而来
dp[i][1] = dp[i][4] + min(dp[k][0]-dp[k][3]);
选一个儿子 需保证所有孙子被覆盖 即 dp[i][4] 然后要选出一个儿子 将他从0~3状态变为选了自己(由于dp[i][4]中他是3状态所以要减去一个dp[k][3]) 取这个差值最小的儿子
dp[i][2] = dp[i][3] + min(dp[k][1]-dp[k][2]);
选一个孙子 与上面类似 要保证所有儿子都被覆盖 即dp[i][3] 再将一个儿子从0~2状态变为0~1状态以保证覆盖他父节点
dp[i][3] = Σdp[j][2];
保证所有儿子被覆盖 儿子的0~2状态均符合条件
dp[i][4] = Σdp[j][3];
保证所有儿子的儿子被覆盖 儿子的0~3状态均符合条件

别问我为什么dp[i][1]和dp[1][2]用到后面的状态 因为你只需要在过程中记下那一坨min的值 把3,4处理完后再算1,2
另外由于数据特殊性 编号大的节点一定是编号小的节点的后代 所以递推顺序直接到着推就好了


代码:(神犇的代码稍作改动)

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn=1000+10;
const int INF=(1<<30);bool G[maxn][maxn];
int dp[maxn][5];
int main()
{int n;cin>>n;for(int i=2,tmp;i<=n;i++){scanf("%d",&tmp);G[tmp][i]=1;}for(int i = n ; i>=1 ; i--){int x1=INF,x2=INF;dp[ i ][ 0 ]=1;for(int j=1;j<=n;j++)if(G[ i ][ j ]){dp[ i ][ 0 ]+=dp[ j ][ 4 ];dp[ i ][ 3 ]+=dp[ j ][ 2 ];dp[ i ][ 4 ]+=dp[ j ][ 3 ];x1=min(x1,dp[ j ][ 0] -dp[ j ][ 3 ]);x2=min(x1,dp[ j ][ 1 ]-dp[ j ][ 2 ]);}dp[ i ][ 1 ]=dp[ i ][ 4 ]+x1;dp[ i ][ 2 ]=min(dp[ i ][ 3 ]+x2,min(dp[ i ][ 0 ],dp[ i ][ 1 ]));dp[ i ][ 3 ]=min(dp[ i ][ 2 ],dp[ i ][ 3 ]);dp[ i ][ 4 ]=min(dp[ i ][ 3 ],dp[ i ][ 4 ]);}printf("%d",dp[ 1 ][ 2 ]);return 0;
}

觉得做完之后对于树形DP有了新的认识 = =涨姿势了

[HNOI]2003 消防局的建立相关推荐

  1. 好书推介---Windows Server 2003企业部署原理与实践

    [原 书 名]  Windows Server 2003:Best Practices for Enterprise Deployments   [原出版社]  McGraw-Hill [作 者] D ...

  2. Exchange 2003 OWA登陆非常慢!

    问题描述: 用户在局域网内部登陆Exchange 2003 OWA的时候,打开登陆页面很快. 输入用户名.密码后,很久才能登陆进OWA页面.(一般都要2分钟) 但是,进去之后的各项操作,速度正常. 而 ...

  3. Windows Storage Server 2003 R2 英文正式版已发布

    飞鸽传书以 Windows Storage Server 2003 R2 简化您的储存需求.无论是您的需求是档案共用.存放区整并.备份与复原.或是复写,Windows Storage Server 2 ...

  4. Fckeditor常见漏洞的挖掘与利用整理汇总

    查看编辑器版本号 FCKeditor/_whatsnew.html ------------------------------------------------------------- 2. V ...

  5. 通过Visual Studio 2005的项目模板来加速开发过程

    page by Ameet Phadnis Feedback     简介: 记得在我第一次做项目的时候,我就在尝试找出一种方法来提高项目开始的效率(jump start my projects).在 ...

  6. 计算机科学与技术专业导向ppt,计算机科学与技术专业导向讲座 第讲.ppt

    计算机科学与技术专业导向讲座 第讲 计算机科学与技术专业 导向讲座 第5章 计算机网络与通信 本章学习目标 本章主要讲解计算机网络与通信的基本知识.计算机网络的应用与操作.对于网络.协议.TCP/IP ...

  7. Fckeditor漏洞汇总

    1.查看编辑器版本 FCKeditor/_whatsnew.html ------------------------------------------------------------- 2. ...

  8. ASP.NET 1.1与ASP.NET 2.0 应用运行并存

    现在有很多老的ASP.NET 1.1的应用,同时我们又开发了ASP.NET 2.0的应用,这是我们在Win 2003的IIS建立站点来时间访问的时候会发现,运行ASP.NET 1.1或ASP.NET ...

  9. Fckeditor漏洞利用总结

    查看编辑器版本 FCKeditor/_whatsnew.html ------------------------------------------------------- ------ 2. V ...

最新文章

  1. matlab ufunc,ufunc函数
  2. AndroidStudio 3.0升级之compile、implementation简要说明
  3. yii框架下使用redis
  4. kubelet启动失败_kubelet 架构浅析
  5. LeetCode 95. 不同的二叉搜索树 II(递归)
  6. Java开发必会Git分布式版本控制系统实战篇
  7. 什么样的架构师才是真正的架构师?
  8. Dll学习心得(2)
  9. 小米发布会之文案错误:大哥你先处罚自己!再处罚相关高管!
  10. Jquery做的网页版连连看(初稿)
  11. 如何炼就数据分析的思维?
  12. 只有微信账号,我可以查询聊天记录吗?
  13. java毕业设计员工绩效考核系统分析与设计Mybatis+系统+数据库+调试部署
  14. 系统安装时出现 \EFI\BOOT\mmx64.sfi -Not Found
  15. Framer:开源原型设计工具,巨头们的心头好
  16. DHD的上网设置与彩信设置
  17. 大数据平台架构技术选型与场景运用
  18. VS2017 如何连接mysql数据库依赖的驱动msi
  19. 今天看漫画不爽,操起ruby...
  20. 智能优化算法——哈里斯鹰算法(Matlab代码实现)

热门文章

  1. go-resiliency源码解析之-timeout
  2. python-word
  3. js秒转换成天时分秒
  4. Windows使用ssh协议远程连接ubuntu linux子系统
  5. 路由器的搭建以及实现虚拟机上网
  6. 【CSDN每日一练 编程题 C语言】严查枪火
  7. 智能钱包系列新一期来了!解读 Devcon VI:Ambire 的创始人为大家带来重要信息!
  8. 计算机应用专业社会环境分析,计算机应用专业人才岗位需求分析调研报告
  9. 国产激光雷达第一股诞生/ 周鸿祎称企业不做ChatGPT将被淘汰/雷军要让小米汽车进世界前五…今日更多新鲜事在此...
  10. zigbee3.0@学习笔记@TI STACK@串口接收