Cut the Sequence

题目link:http://poj.org/problem?id=3017

Part1:

首先拿到这道题,先得出普通的 dp。

设 f_i 表示将前 i 个数按最优方案分为几个合法的区间的最大值之和。

那么容易得出 dp 方程:

f_i = min{ f_j + Max(j + 1, i) } (0 ≤ j ≤ i - 1 && Sum(j + 1, i) ≤ m);

其中 Max(x, y) 表示 max{ a_i } (x ≤ i ≤ y),Sum(x, y) 表示 Σ a_i (x ≤ i ≤ y)。

Part2:

这时容易发现这个题很难直接用单调队列进行优化,那么考虑通过决策单调性来考虑这个问题。

那么就来考虑用哪个 j 来转移最优。

但是显然这个并不是太好考虑,那先来考虑用 j 来转移比用 j - 1 来转移更优的条件是什么。

容易得出只有两种情况:

Sum(j, i) > m && Sum(j + 1, i) ≤ m;

f_j + Max(j + 1, i) < f_{j - 1} + Max(j, i);

那么满足这两种情况之一就变成了 j 是最优转移的必要条件。

但是好像这个题不能像普通的单调队列优化 dp 的题一样来找到队首这样一个唯一的最优解,那么现在只能去考虑一下找到一些 j,使得最优的转移包含在这些 j 里面就行了(dp 虽然需要不漏,但是不需要不重)。

那么现在就考虑如何去找到上面的两种情况的 j 并依次进行转移就行了。

Part2.1:

这里第一种情况比较容易考虑。

容易得到对于每一个 i 来说,这样的 j 只可能会存在一个(因为它是一个分界点)。

然后就可以二分去找这样的 j,具体实现可以使用 STL 中的 lower_bound 函数(找到第一个大于或等于 Sum(1, i) - m 的 Sum(1, j),j 就是答案)。

Part2.2:

这里可能会较为困难一些,那么先看一看 f_j 和 f_{j - 1} 的关系。

它们的关系其实是 f_j ≥ f_{j - 1},这里给出证明:

考虑使用前 j 个数的最优分区间方案的分界点去分前 j 个数,这里容易证明这样是一个分前 j - 1 个数的合法的方案,但不一定是最优的方案,并且也容易证明这样分的所有区间最大值之和是小于或等于前 j 个数的最优方案的所有区间最大值之和的(因为只会有最后一个区间的数比前 j 个数的方案的最后一个区间的数少一个,但是最后一个区间的最大值不可能比前 j 个数的大)。所以既然如这般如此,仅仅是一个合法的方案就比前 j 个数的最优方案要好(或相等),那 f_j 一定大于或等于 f_{j - 1},证毕。

既然 f_j ≥ f_{j - 1},还想要 f_j + Max(j + 1, i) < f_{j - 1} + Max(j, i),那么必须就得 Max(j + 1, i) < Max(j, i),化简一下就是 a_j = Max(i, j)。

那么现在就是考虑把上面这个化简过的式子里的 j 给都找到并进行转移了,于是考虑接着进行转化

 

Cut the Sequence

上一篇:SharePoint 2013实例1—构建三层服务器场8—配置WEB层


下一篇:学习linux第十一课!bonding网络配置、ssh远程服务、screen不间断会话