E. Maximum Monogonosity

发布时间 2023-08-14 20:25:36作者: onlyblues

E. Maximum Monogonosity

You are given an array $a$ of length $n$ and an array $b$ of length $n$. The cost of a segment $[l, r]$, $1 \le l \le r \le n$, is defined as $|b_l - a_r| + |b_r - a_l|$.

Recall that two segments $[l_1, r_1]$, $1 \le l_1 \le r_1 \le n$, and $[l_2, r_2]$, $1 \le l_2 \le r_2 \le n$, are non-intersecting if one of the following conditions is satisfied: $r_1 < l_2$ or $r_2 < l_1$.

The length of a segment $[l, r]$, $1 \le l \le r \le n$, is defined as $r - l + 1$.

Find the maximum possible sum of costs of non-intersecting segments $[l_j, r_j]$, $1 \le l_j \le r_j \le n$, whose total length is equal to $k$.

Input

Each test consists of multiple test cases. The first line contains a single integer $t$ $(1 \le t \le 1000)$ — the number of sets of input data. The description of the test cases follows.

The first line of each test case contains two integers $n$ and $k$ ($1 \le k \le n \le 3000$) — the length of array $a$ and the total length of segments.

The second line of each test case contains $n$ integers $a_1, a_2, \ldots, a_n$ ($-10^9 \le a_i \le 10^9$) — the elements of array $a$.

The third line of each test case contains $n$ integers $b_1, b_2, \ldots, b_n$ ($-10^9 \le b_i \le 10^9$) — the elements of array $b$.

It is guaranteed that the sum of $n$ over all test case does not exceed $3000$.

Output

For each test case, output a single number — the maximum possible sum of costs of such segments.

Example

input

5
4 4
1 1 1 1
1 1 1 1
3 2
1 3 2
5 2 3
5 1
1 2 3 4 5
1 2 3 4 5
7 2
1 3 7 6 4 7 2
1 5 3 2 7 4 5
4 2
17 3 5 8
16 2 5 9

output

0
10
0
16
28

Note

In the first test case, the cost of any segment is $0$, so the total cost is $0$.

In the second test case, we can take the segment $[1, 1]$ with a cost of $8$ and the segment $[3, 3]$ with a cost of $2$ to get a total sum of $10$. It can be shown that this is the optimal solution.

In the third test case, we are only interested in segments of length $1$, and the cost of any such segment is $0$.

In the fourth test case, it can be shown that the optimal sum is $16$. For example, we can take the segments $[3, 3]$ and $[4, 4]$.

 

解题思路

  最直接的dp做法还是很容易想到的,定义状态$f(i,j)$表示从前$i$个数中选出了总长度为$j$且互不相交的区间的所有方案中的最大值。根据以第$i$个数为右端点的区间长度进行状态划分,因此状态转移方程就是$$f(i,j) = \max\left\{ {f(i-1,j), \ \max_{1 \leq u \leq \min \left\{ {j,k} \right\}}\left\{ {f(i-u, j-u) + \left| {a_i-b_{i-u+1}} \right| + \left| {a_{i-u+1}-b_{i}} \right|} \right\}} \right\} \quad (j \leq i)$$

  可以发现整个dp的时间复杂度是$O(n \cdot k^2)$,因此需要对状态表示或状态转移进行优化。当时想着推状态转移的式子然后找规律再结合数据结构来优化,结果发现好像不行,至少我没有做出来。然后看题解发现是对状态转移方程进行改写然后再优化,这个我肯定是想不到了。

  对于$\left| a_l - b_r \right| + \left| a_r - b_l \right|$,其实是等价于$$\left| a_l - b_r \right| + \left| a_r - b_l \right| = \max\left\{ {b_l - a_r + b_r - a_l, \, b_l - a_r - b_r + a_l, \, -b_l + a_r + b_r - a_l, \, -b_l + a_r - b_r + a_l} \right\}$$

  即我们只需对这$4$中组合求最大值即可,因此状态转移方程可以改写成如下形式:$$\begin{align*} f(i,j) &= \max\left\{ {f(i-1,j), \ \max_{1 \leq u \leq \min \left\{ {j,k} \right\}}\left\{ {f(i-u, j-u) + \left| {a_i-b_{i-u+1}} \right| + \left| {a_{i-u+1}-b_{i}} \right|} \right\}} \right\} \\\\ &= \max\Big\{ f(i-1,j), \\ & \qquad\quad \max_{1 \leq u \leq \min \left\{ {j,k} \right\}}\left\{ {f(i-u, j-u) - a_{i-u+1} + b_{i-u+1}} \right\} - a_i + b_i, \\ & \qquad\quad \max_{1 \leq u \leq \min \left\{ {j,k} \right\}}\left\{ {f(i-u, j-u) + a_{i-u+1} + b_{i-u+1}} \right\} - a_i - b_i, \\ & \qquad\quad \max_{1 \leq u \leq \min \left\{ {j,k} \right\}}\left\{ {f(i-u, j-u) - a_{i-u+1} - b_{i-u+1}} \right\} + a_i + b_i, \\ & \qquad\quad \max_{1 \leq u \leq \min \left\{ {j,k} \right\}}\left\{ {f(i-u, j-u) + a_{i-u+1} - b_{i-u+1}} \right\} + a_i - b_i \Big\} \\ \end{align*}$$

  可以发现,状态$f(i,j)$总是通过$f(i-u,j-u)$转移得到,而$i-u - (j-u) = i-j$,即只要满足状态第一维减去第二维等于$i-j$,那么就可以转移到$f(i,j)$。形象点理解的话,可以把$n \times k$个状态看作是一个矩阵,$f(i,j)$表示矩阵中第$i$行第$j$列的元素,那么$f(i,j)$就可以从其所在的对角线之上的所有格子(状态)转移过来,如下图:

  例如状态$f(7, 4)$就可以从$f(6,3)$,$f(5,2)$,$f(4,2)$转移过来。这有点类似于从某个前缀转移得到,不过在这里是斜线的前缀。一样的,我们可以用$i-j$来代表某条斜线,然后分别维护每条斜线关于$f(i,j)-a_{i+1}+b_{i+1}$,$f(i,j)+a_{i+1}+b_{i+1}$,$f(i,j)-a_{i+1}-b_{i+1}$,$f(i,j)+a_{i+1}-b_{i+1}$的前缀最大值,这样在状态转移时就可以降到$O(1)$。

  AC代码如下,时间复杂度为$O(n \cdot k)$:

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

 

解题思路

  Codeforces Round #892 (Div. 2) Editorial:Codeforces Round #892 (Div. 2) Editorial - Codeforces