斜率优化DP

来源:互联网 发布:库里2016总决赛数据 编辑:程序博客网 时间:2024/05/16 09:36

当DP的时间复杂度大于时限的时候,我们就要对DP进行优化。其中一个比较常用的就是用单调队列优化DP。
单调队列优化DP的思想是:减小最优解的搜索空间,提高状态转移的效率。和搜索中的剪枝一样。
单调队列通过下面的操作来缩小最优解的空间:
1.队首元素保留最优解。不是最优解的队首元素需要被删除。
2.整个队列保持单调性或者是下凸性。新加入的元素如果破坏这条性质,需要从尾部把旧元素删除,直到该性质得到满足。
因为,每个元素至多进队入队一次,这样平摊下来,上面的操作就是Θ(1) 
第一种类型的题就是维护单调性。
见:最长上升子序列,滑动最小值,多重背包的单调队列优化
第二种类型的题就是维护下凸性。
这样的题目的类型比较多,这些题会出现下面的特征:
1.状态转移方程中,出现二次项和常数项。
2.状态转移方程中,某一项(非dp)为单调递增函数。
3.dp的值满足单调性。
第一个和第二个特征的结合,我们就能将斜率表达出来。
第二个特征,能够实现单调队列的第一个操作。
第三个特征,能够实现单调队列的第二个操作。

单调队列的框架:

for(int i = 0 ; i < N; ++i){    head = 0, tail = -1;    while(head < tail && !sat(q[tail],q[tail - 1])) tail--;    q[++tail] = i;    while(head < tail && !sat(q[head],q[head + 1])) head++;    dp[i] = ...;}
0 0
原创粉丝点击