D - The Bakery CodeForces - 834D 线段树优化dp···

D - The Bakery

 CodeForces - 834D 

这个题目好难啊,我理解了好久,都没有怎么理解好,

这种线段树优化dp,感觉还是很难的。

直接说思路吧,说不清楚就看代码吧。

这个题目转移方程还是很好写的,

dp[i][j]表示前面 i 个蛋糕 分成了 j 个数字的最大价值。

dp[i][j]=max(dp[k][j-1]+val[k+1~i]

显而易见的是,这个肯定不可以直接暴力求,所以就要用到线段树优化。

线段树怎么优化呢,

先看这个问题,给你一个点 x ,问你以这个点为右端点的所有区间有多少种数字,

这个很简单是不是,那继续问你 从x 到 x+1 这个点怎么转移?

是不是找到 last[a[x+1]  上一次出现a[x+1] 这个数字的位置,从这个位置+1到 x+1 这个位置,所有的区间都+1

这个是不是就是线段树的更新,那么线段树的每一个位置是不是随着我们对 i 的枚举,每一个叶子节点 就是l==r==k 是不是 val[k~i]

知道这个了,回到之前的问题,我们要求val[k+1~i]+dp[k][j-1]的最大值

因为这个dp[k][j-1]上一次已经求出来了,对这一次不产生任何影响了,是一个定值。

我们就只需要求val[k+1~j]

所以可以把这两个东西一起放到线段树里面,但是一个是l==r==k这个位置,一个是k+1这个位置,所以需要val往前面挪一下,或者dp[k]往后挪一下。

我选择第一种,那么就是每次更新,就更新 last[a[x+1]] 到 x 这个位置。

猜你喜欢

转载自www.cnblogs.com/EchoZQN/p/11353079.html
今日推荐