D. Maximum Subarray

D. Maximum Subarray

You are given an array $a_1, a_2, \dots, a_n$, consisting of $n$ integers. You are also given two integers $k$ and $x$.

You have to perform the following operation exactly once: add $x$ to the elements on exactly $k$ distinct positions, and subtract $x$ from all the others.

For example, if $a = [2, -1, 2, 3]$, $k = 1$, $x = 2$, and we have picked the first element, then after the operation the array $a = [4, -3, 0, 1]$.

Let $f(a)$ be the maximum possible sum of a subarray of $a$. The subarray of $a$ is a contiguous part of the array $a$, i. e. the array $a_i, a_{i + 1}, \dots, a_j$ for some $1 \le i \le j \le n$. An empty subarray should also be considered, it has sum $0$.

Let the array $a'$ be the array $a$ after applying the aforementioned operation. Apply the operation in such a way that $f(a')$ is the maximum possible, and print the maximum possible value of $f(a')$.

Input

The first line contains a single integer $t$ ($1 \le t \le 10^4$) — the number of test cases.

The first line of each test case contains three integers $n$, $k$ and $x$ ($1 \le n \le 2 \cdot 10^5$; $0 \le k \le \min(20, n)$; $-10^9 \le x \le 10^9$).

The second line contains $n$ integers $a_1, a_2, \dots, a_n$ ($-10^9 \le a_i \le 10^9$).

The sum of $n$ over all test cases doesn't exceed $2 \cdot 10^5$.

Output

For each test case, print one integer — the maximum possible value of $f(a')$.

Example

input

4
4 1 2
2 -1 2 3
2 2 3
-1 2
3 0 5
3 2 4
6 2 -8
4 -1 9 -3 7 -8

output

5
7
0
44

 

解题思路

  一开始还真没想到用dp。

  定义状态$f(i, j)$表示在前$i$个数中,所有选择了第$i$个数且选择了$j$个不同位置加上$x$的连续子段和方案的集合,属性就是所有方案中连续子段和的最大值。根据第$i$个数所在的连续子段所包含的数,即只有第$i$个数或还有第$i-1$个数所构成的连续子段,以及第$i$个数是加上$x$还是减去$x$来划分方案。因此状态转移方程就是

$$f(i,j) =
\begin{cases}
\max \{ {a_i - x, \ f(i-1,j) + a_i - x} \}, &(j < i) &(1)  \\
\max \{ {a_i + x, \ f(i-1,j-1) + a_i + x} \}, &(j > 0) &(2) 
\end{cases}$$

  其中$(1)$式的条件意味着,如果有$j=i$那么$1 \sim i$中的数都必须要加上$x$,因此第$i$个数必须加上$x$,而不能减去$x$。

  如果$j$同时满足两个条件,那么$f(i,j)$就是$(1)$式和$(2)$式的最大值。

  其中对于每个$i$,$j$都对应着一个合法的范围。首先很明显$j$要同时满足$j \leq i$且$j \leq k$,还要有$j + n - i \geq k$即后面的$n-i$个数加上$j$至少要有$k$个,否则如果后面$n-i$个数全加上$x$再加上前面的$j$个还不足$k$个,就不满足题目要求了。因此$j \in \left[\max \{ 0, k-n+1 \}, \ \min \{ i, k \} \right]$。

  AC代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 
 6 const int N = 2e5 + 10, M = 30;
 7 
 8 int a[N];
 9 LL f[N][M];
10 
11 void solve() {
12     int n, m, k;
13     scanf("%d %d %d", &n, &m, &k);
14     for (int i = 1; i <= n; i++) {
15         scanf("%d", a + i);
16     }
17     for (int i = 0; i <= n; i++) {
18         for (int j = 0; j <= m; j++) {
19             f[i][j] = -0x3f3f3f3f3f3f3f3f;
20         }
21     }
22     f[0][0] = 0;
23     LL ret = 0;
24     for (int i = 1; i <= n; i++) {
25         for (int j = max(0, m - n + i); j <= m && j <= i; j++) {
26             if (j < i) f[i][j] = max(0ll, f[i - 1][j]) + a[i] - k;
27             if (j) f[i][j] = max(f[i][j], max(0ll, f[i - 1][j - 1]) + a[i] + k);
28             ret = max(ret, f[i][j]);
29         }
30     }
31     printf("%lld\n", ret);
32 }
33 
34 int main() {
35     int t;
36     scanf("%d", &t);
37     while (t--) {
38         solve();
39     }
40     
41     return 0;
42 }

 

参考资料

  Educational Codeforces Round 144 Editorial:https://codeforces.com/blog/entry/113408

posted @ 2023-03-04 10:14  onlyblues  阅读(132)  评论(0编辑  收藏  举报
Web Analytics