[Luogu] P2389 电脑班的裁员
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)\)