Description
给定一个长度为 $n$ 的序列 $\{v\}$,你最多可以进行 $m$ 次操作,操作有 $4$ 种:
- 把最左端的数放在手里;
- 把最右端的数放在手里;
- 把手中的某个数放回序列最左端;
- 把手中的某个数放回序列最右端。
求手中数的总和最大是多少。$(1 \leq n \leq 50,1 \leq m \leq 100,-10^7 \leq v_i \leq 10^7)$
Source
Solution
显然答案一定是先从左边取若干数,放回取走的若干数;再从右边取若干数,放回取走的若干数。取和放的操作总数不超过 $m$ 。
尝试 动态规划 。
我们用 $f_{i,j}$ 表示取前 $i$ 个数,其中放回 $j$ 个数的最大价值,$g_{i,j}$ 表示取末尾 $i$ 个数,其中放回 $j$ 个数的最大价值。
其实只要会求 $f$,翻转数组求能用同样的方法求 $g$ 了。
对于 $f_{i,j}$,考虑第 $i$ 个数选还是不选。
如果选,取前 $i - 1$ 个数放回 $j$ 个数的最大价值为 $f_{i-1,j}$,还要加上 $v_i$ 。
如果不选,那么只能取前 $i - 1$ 个数并放回 $j - 1$ 个数,最大价值为 $f_{i-1,j-1}$ 。
取上述两个值的较大值即可。
即
最后通过 $f$ 和 $g$ 合并答案即可,注意 $m$ 次操作不一定要用完。$\rm DP$ 时间复杂度为 $O(nm)$,合并复杂度为 $O(n^2m^2)$ 。
Code
1 |
|