当前位置:首页 > 动态规划 > 单调DP > 正文
SSOJ2893打印文章
1163+

题目大意:n个单词分成连续的若干段,每一段的费用为单词长度和的平方加m,求最下总费用。

原题来自:HDU 3507

给出 $N$ 个单词,每个单词有个非负权值 $C_i$ ,现要将它们分成连续的若干段,每段的代价为此段单词的权值和的平方,还要加一个常数 $M$,即 $(\sum C_i)^2+M$。现在想求出一种最优方案,使得总费用之和最小。

【输入】

包含多组测试数据,对于每组测试数据:

第一行包含两个整数 $N$ 和 $M$。

第二行为 $N$ 个整数。

【输出】

输出仅一个整数,表示最小的价值。

【输入样例】

5 5
5 9 5 7 5

【输出样例】

230

【提示】

数据范围与提示:\n对于全部数据,$0\le N\le 5 × 10^5,0\le M\le 1000$。

解题思路

状态转移方程:$f[i] = f[j] + (s[i]-s[j])^2 + v$

拆开移项可得:$f[i] + 2*s[i] * s[j] = f[j]+s[j]^2 + s[i]^2+v$

拆法:包含j的是变量,仅包含j的多项式放在一边,包含i和j的多项式放在另一边,即可得到一个斜率式子。

如看成y=kx+b,那么上式的y是$f[j]+s[j]^2$,x是s[j],斜率是2*s[i],b是个常数可以暂时不管。

由此,可以define出代码的3~6行。

1、在转移的时候,i的前驱有多个,对于两个前驱哪个好?两点形成的斜率小于k则后面的好!

在斜率k=2*s[i]确定的情况下,由于我们要求的是最小值,需要第一个碰到的点是“最低”的点,直线往上平移,斜率小会先碰到右边点,斜率大会先碰到左边点。

2、考虑维护斜率递增或者递减,这里维护递增,为什么?

如果斜率出现递减,那么中间那个点永远不会用于转移,因为ab斜率大则a好,如果b比a好,ab斜率小,bc斜率更小,那么c比b好。

因为斜率k随着i递增而递增,所以选择的时候,从头开始,遇到斜率小的删除队头;入队前,如果发现斜率递减,删除队尾。最优决策在开头。

程序实现

About

坚决不Copy代码!

本文标签:,,,,,,,,,

报歉!评论已关闭.