[Luogu] P2389 电脑班的裁员

\(Link\)

Description

\(n\)个数中取不大于\(k\)段连续的数,使取的数总和最大。

Solution

Sol1

裸DP。
\(dp(i, j)\) 表示前 \(i\) 个数取 \(j\) 段的最大价值。
若不选,则

\[dp(i, j)=dp(i-1, j) \]

若选,枚举最后一段的起始位置 \(k\) :

\[dp(i, j)=\max \left\{dp(k, j-1)+s_{i}-s_{k}\right\}(k<i) \]

其中 \(s_{i}\) 表示前 \(i\) 个数的前缀和。
根据方程,三重循环枚举 \(i, j, k\) 即可。
答案为 \(dp(n, m),\) 复杂度 \(O\left(n^{3}\right)_{\circ}\)

Sol2

学习了一种DP优化方法。即改变枚举顺序,将和某些变量一起提出来,维护前缀最大值。

我们设 \(g(k, j)=dp(k, j)-s_{k},\)

\[dp(i, j)=\max \left\{dp(i-1, j), g(k, j)+s_{i}\right\}(k<i) \]

只要维护出 \(g(k, j)\) 的最大值,就不需要枚举 $k $了。
具体地,先枚举 \(j\) 后枚举 \(i,\) 因为 \(k<i,\) 在枚举 \(i\) 的时候顺便维护出 \(g(1\)\(i-1, j)\) 的最大值 \(g_{\max }\) ,转移的时侯直接用 \(g_{\max }\) 转移即可。
答案为 \(dp(n, m),\) 复杂度 \(O\left(n^{2}\right)\)

posted @ 2020-10-23 11:57  andysj  阅读(57)  评论(0编辑  收藏  举报