P3780 苹果树 题解

传送门

夏天近了,又到了恋爱的季节,小Q家门前的苹果树上结满了红红圆圆的苹果。

这株苹果树是一个有着n个结点的有根树,其中结点被依次编号为1n1号结点为根,其余每一个结点的父结点一定是某个编号较小的结点。每一个结点上都有一些苹果,第i个结点上有ai(ai>0)个苹果,每取走其中一个苹果就可以得到vi(vi>0)的幸福度(若在这个结点取走kai个苹果,则可以收获kvi的幸福度)。如果在一个结点取走了至少一个苹果,则必须要在其父结点处取走至少一个苹果。

现在,给定正整数k,请从树上取走若干苹果。如果总计取走了t个苹果,且所有取了至少一个苹果的那些结点的最大深度为h(这里规定根结点的深度为1),则要求thk。问最大可以收获多少的幸福度?(这些幸福度全都归属于恋爱中的小Q。)

多组数据,T5,n2×104,k5×105,nk25×106,ai108,vi100


选一个包含根的连通块,thk,最大价值。算法明显是 O(nk) 的。

【简化版】

因为 thk 这个条件过于阴间了,尝试解决简化版 tk

av=1

即使是简化版,也先考虑解决 av=1 的特殊情况。这种情况,每个结点只有选和不选两种情况。

采用 dfn 序 DP。dp[i][j] 表示目前考虑完 dfni1 的结点(i 待定),已经选了 j 个结点,且强制 i 的祖先们都选了,最大权值是多少。

刷表法转移,考虑 i 选不选。若 i 选,转移到 dp[i+1][j+1];若 i 不选,记 big[x]x 子树中 dfn 的最大值,转移到 dp[big[i]+1][j]

答案取 maxdp[n+1][0n]。状态 O(nk),转移 O(1),总共 O(nk) 的复杂度。

av 任意】

然后解决简化版的一般情况。状态描述不变,考虑怎么优化转移过程。

先考虑朴素的转移是怎么做的。若选 0 个,转移到 dp[big[i]+1][j];否则 dp[i][j]+wi×cdp[i+1][j+c],要求 c1

不选的情况不用动,只需要优化选的情况。

gj=max1jcai,c1{dp[i][c]+wi(jc)}=wij+max1jcai,c1dp[i][c]wic。把 dp[i][c]wic 视作 f[c],就是经典的滑动窗口问题,可以 O(k) 求出 g0gk
然后用 gk 转移 dp[i+1][k]

还是 O(nk) 的。

【原版】

h 可以看作是 "允许让一条链上的点免费取一个"。

av=1

新建一个 dfn2 序,和上面的 dfn 对儿子的访问顺序完全相反。然后新建一个 dp2[][] 按照 dfn2 的顺序 DP,状态定义和 dp[][] 一样。

在求出两个数组之后,枚举结点 v 为 "免费链" 的最下端结点,枚举 j1 为 "dfn 比 v 小的选的个数",dp[v][j1]+dp2[v][j2]+wv 即为 v 的最大可能贡献。其中 j2 满足 j1(d[v]1)+j2(d[v]1)=k
之所以加上 wv,是因为两个状态定义里 v 都是待定的,所以在最后把这个免费的 v 的权值加上。

av 任意】

这里不能按上面做的原因,是 v 的祖先可以选不止一个,在 dp[v] 中是一种选法,在 dp2[v] 中又是不同的选法,情况不同当然不能直接合并。

那能不能让 v 的祖先的 a=1 呢?就相当于除了叶子结点的 a 都等于 1

事实上是可以的,我们拆点,若 ai>1,给 i 额外拆出一个结点 new 作为儿子,a[new]=a[i]1,w[new]=w[i] 然后 a[i]1。这是等价的。


题解区第一篇是按照后序遍历的 dfn 写的,本质相同。

posted @   FLY_lai  阅读(39)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示