【树形DP】树

这是一篇关于树形动态规划的博客,讨论如何计算最少操作次数以使树上的所有节点指示灯点亮。文章通过举例和状态转移方程解析了问题,并提供了代码实现。
摘要由CSDN通过智能技术生成

树(tree)


【问题描述】
图论中的树为一个无环的无向图。给定一棵树,每个节点有一盏指示灯和一个按钮。如果节点的按扭被按了,那么该节点的灯会从熄灭变为点亮(当按之前是熄灭的),或者从点亮到熄灭(当按之前是点亮的)。并且该节点的直接邻居也发生同样的变化。 开始的时候,所有的指示灯都是熄灭的。请编程计算最少要按多少次按钮,才能让所有节点的指示灯变为点亮状态。
【输入格式】
输入文件有多组数据。
输入第一行包含一个整数n,表示树的节点数目。每个节点的编号从1到n。
输入接下来的n – 1行,每一行包含两个整数x,y,表示节点x和y之间有一条无向边。
当输入n为0时,表示输入结束。
【输出格式】
对于每组数据,输出最少要按多少次按钮,才能让所有节点的指示灯变为点亮状态。每一组数据独占一行。

输入样例:
3
1 2
1 3
0
输出样例:
1

这道题目莫名让我想到了以前见过有一个死胖子用手指按字母然后附近的都会点到,不过我忘记题目了~~
言归正传,题目已经很明确告诉你是一棵树,那么就可以很容易想到是树形DP,寻找状态转移方程是本题的关键。
首先,我们用f[x][0]表示以x为根节点的子树下,x开着灯,而他的儿子,孙子,孙子的儿子…也都开灯的最少次数;

f[x][1]表示以x为根节点的子树下,x关灯,而他的子辈都开着灯的最少次数;

f[x][2]则表示以x为根节点的子树下,x关灯,他的子辈也都关灯的最少次数;

那么f[x][3]表示什么呢,就是以x为根节点的子树下,x开灯,他的子辈也都关灯的最少次数,很显然,这是不存在的,所以f[x][3]排除啦。

把F数组的定义弄清楚了,那么接下来的就好办了!
也是分三步:
1. f[x][0]最好算,因为如果我和我的子辈都开着灯了,那么我的亲朋好友就不用开灯了啦,所以f[x][0]+=f[x][2]

2.接着就算f[x][2]f[x][1]怎么算呢?因为我们还要考虑到有可能在我的子辈按按钮按了个奇数,那么最后的状态就要改变呀(ps:真是个无聊的儿子。。),所以我需要一个变量来算我途中按了多少次(这个变量我称为按钮计数)。然后就是如何“科学的推卸责任了”,我们也要用一个变量,来表示最少次数,那就是tmp+=min(f[x][2],f[x][1])啦!

3.f[x][2]和f[x][1]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值