只会K子段最大权值和,对于这道题。。。思路代码都是抄的。。。
题解大概是说
∑|si−si+1|=>∑si−si+1||∑−si+si+1然后两种情况取个最大值
#include <bits/stdc++.h>
using namespace std;
const int inf = 1000000007;
int dp[405][55][2];
int n , k , a[405];
inline int sum (int l , int r) {
return a[r] - a[l - 1];
}
int main () {
#ifdef DouBi
freopen("in.cpp","r",stdin);
#endif // DouBi
while(scanf("%d%d",&n,&k)!=EOF){
a[0] = 0;
for (int i = 1 ; i <= n ; i ++) {
cin >> a[i];
a[i] += a[i - 1];
}
for (int i = 0 ; i <= n ; i ++)
for (int j = 0 ; j <= k ; j ++)
for (int p = 0 ; p < 2 ; p ++)
dp[i][j][p] = -inf;
int ans = -inf;
for (int i = 1 ; i <= n ; i ++) {
for (int j = 1 ; j <= i ; j ++) {
dp[i][1][0] = max (dp[i][1][0] , -sum (j , i));
dp[i][1][1] = max (dp[i][1][1] , sum (j , i));
}
for (int j = 1 ; j < k ; j ++) {
for (int p = 2 ; p <= i ; p ++) {
int ret = sum (p , i);
if (dp[p-1][j][0] != -inf) {
ret += dp[p - 1][j][0];
if (j == k - 1)
ans = max (ans , ret);
ret += sum (p , i);
dp[i][j + 1][1] = max (ret, dp[i][j + 1][1]);
ret -= sum (p , i) * 2;
dp[i][j + 1][0] = max (ret, dp[i][j + 1][0]);
}
ret = -sum (p , i);
if (dp[p-1][j][1] != -inf) {
ret += dp[p - 1][j][1];
if (j == k - 1)
ans = max (ans , ret);
ret -= sum (p , i);
dp[i][j + 1][0] = max (ret, dp[i][j + 1][0]);
ret += sum (p , i) * 2;
dp[i][j + 1][1] = max (ret, dp[i][j + 1][1]);
}
}
}
for (int j = 1 ; j <= k ; j ++) {
dp[i][j][0] = max (dp[i][j][0] , dp[i - 1][j][0]);
dp[i][j][1] = max (dp[i][j][1] , dp[i - 1][j][1]);
}
}
printf ("%d\n" , ans);
}
return 0;
}