线段树+dp

Posted tzy666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树+dp相关的知识,希望对你有一定的参考价值。

题目传送门:https://ac.nowcoder.com/acm/contest/4743/E

题解:可以翻看我的提交记录。


首先,让我们看看问题不修改的话我们怎么做。
dpi,jdp_{i,j}dpi,j?表示第iii堆石子搬运jjj次需要的最小代价。对于单堆石子,最优的策略是把aia_iai?个石子均分在jjj次搬运上。可以证明这是最优的策略:
假设这样产生的花费为sumsumsum,而每次搬运的个数都为xxx,我们把某次搬运的个数−1-11,加到另一次搬运上,重新计算的花费为sum−(x∗x−(x−1)∗(x−1))+((x+1)∗(x+1)−x∗x)sum-(x*x-(x-1)*(x-1))+((x+1)*(x+1)-x*x)sum(xx(x1)(x1))+((x+1)(x+1)xx),对于任意的x>0x>0x>0,一定有(x+1)∗(x+1)−x∗x>x∗x−(x−1)∗(x−1)(x+1)*(x+1)-x*x>x*x-(x-1)*(x-1)(x+1)(x+1)xx>xx(x1)(x1),那么花费增加了。
再考虑两堆石子x,yx,yx,y,我们知道dpx,k1dp_{x,k_1}dpx,k1??dpy,k2dp_{y,k_2}dpy,k2??,另dpz,jdp_{z,j}dpz,j?表示两堆搬运jjj次全部搬完的代码,有dpz,k1+k2=min(dpx,k1+dpy,k2)dp_{z,k_1+k_2}=min(dp_{x,k_1}+dp_{y,k_2})dpz,k1?+k2??=min(dpx,k1??+dpy,k2??)。
如果没有修改,我们从前往后遍历进行dpdpdp得出答案,这样单次处理的时间复杂度为O(n3)O(n^3)O(n3)。如果处理qqq次,因为n,qn,qn,q同阶,时间复杂度为O(n4)O(n^4)O(n4),但复杂度太高会得到TLETLETLE。
注意到本题每次仅修改一个点,那么是否可以把dpdpdp稍做修改,使得每次修改后可以快速得出答案呢?这显然是可以的,考虑444堆石子x1,x2,x3,x4x_1,x_2,x_3,x_4x1?,x2?,x3?,x4?,我们先合并x1,x2x_1,x_2x1?,x2?的答案,再合并x3,x4x_3,x_4x3?,x4?的答案,再将x1,x2x_1,x_2x1?,x2?x3,x4x_3,x_4x3?,x4?的答案合并,这不影响最终的结果。
这样,我们可以采用分治的思想来进行dpdpdp(类似于线段树),因为最多4∗n4*n4n个结点,所以初始化的时间复杂度为n3n^3n3。,但对于后面的每次修改,就相当于线段树单点修改,单点修改的时间复杂度为n2lognn^2lognn2logn,总的时间复杂度O(n3logn)O(n^3logn)O(n3logn),发现这样复杂度其实也挺大的,但别忘了还有一个小技巧sizesizesize优化,利用sizesizesize优化后时间跑不满,足以通过这道题。

 

以上是关于线段树+dp的主要内容,如果未能解决你的问题,请参考以下文章

降临(线段树优化dp)

HDU 3698 DP+线段树

HDU 4521 小明系列问题——小明序列 (线段树维护DP)

bzoj5123[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索

P1442 铁球落地(线段树dp)

Man Down(线段树dp)