迷宫

其实他这个DP状态解释的有一点问题,终点不一定非要是i

其实就是在i的子树中找一条链,满足i是一个端点,然后另一个端点是否有陷阱(行进方向到时候再具体讨论,除了一些特殊状态,i为起点或终点都是可以的);然后一定要注意,这个状态是从起点到终点经过j个陷阱的最优值,也就是说,走到终点之后完全有可能再继续延长这条路径,但是走到终点时,累积经过的陷阱数就是j

于是就可以好好理解上面的转移过程了;然后最开始的初始化过程指的是起点终点都是根的情况,所以要这么初始化(从下面的main函数来看,dp数组是被初始化为负无穷的,负无穷代表不合法状态)

这个更新答案的过程感觉没必要这么复杂,不太好理解,感觉讨论一条链的陷阱个数j,然后另一条链的陷阱个数就是Cj了,然后讨论一下方向是否正确

注意这个代码用了树形DP求树的直径的类似的做法

update 2024.6.29

这里当然可以用换根DP,然而,我们也可以记一下,这里由于是一条链,在某一颗以x为根的子树中,链的情况无非就两种,一种是以x为起点,另一种就是以x为转折点,而这两种情况都可以转化为以x为根的树形DP,所以链的情况就可以不用换根DP了

为什么最开始枚举每个节点都是根节点的时候,可以不用设第三维呢?这就是因为如果枚举每个根节点的话,当前被枚举的这个根节点一定是起点,也就不会导致答案的丢失。比如说一条路径一个端点没有陷阱另一个端点有陷阱,但是只允许经过一个陷阱,那么显然起点只能是哪个没有陷阱的端点,然而如果我们指定了有陷阱的端点是根节点的话,显然这条路径(如果我们的状态不开第三维)就不会被枚举到了,这就要求我们再指定没有陷阱的端点为根节点,然后再做一次DP来覆盖这个答案

update 2024.8.31

上面的DP数组是自适应方向的,其实更好理解的方式应该是我们手动规定一个方向,设f[i][j][0/1]表示以i为起点/终点向子树走经过j个陷阱的最大价值。这样子肯定不会遗漏最优解。心路历程:我们考虑将x作为起点,从x向其子树走是非常容易DP的,但是从x向父亲走的这种情况我们没有考虑到,这个时候我们可能会想换根DP,但是就像我们上面说的一样,此时的情况就是一条链,而链一定会以某个根作为转折点,所以此时就用普通的树形DP就可以了,我们没有考虑到的这种情况很显然可以被覆盖,只需要维护根节点是起点或是终点的两种情况就好了

posted @   最爱丁珰  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示