传送门
首先答案一定是
∑
i
=
1
n
b
i
a
i
,
(
b
i
=
−
1
,
1
)
\sum_{i=1}^nb_ia_i,(b_i=-1,1)
∑i=1nbiai,(bi=−1,1)。
我们考虑最终的答案中的
{
b
i
}
\{b_i\}
{bi}序列有何性质,假设其中
−
1
-1
−1有
x
x
x个,
1
1
1有
y
y
y个,那么满足
(
2
x
+
y
)
%
3
=
1
(2x+y)\%3=1
(2x+y)%3=1。
这个可以通过打表看出(我其实看不出 ),这里给出一个证明:
利用数学归纳法来证明,每次我们都会合并两个序列,考虑两个序列的性质,若两个序列都满足
(
2
x
+
y
)
%
3
=
1
(2x+y)\%3=1
(2x+y)%3=1,假设第一个序列
(
x
1
,
y
1
)
(x_1,y_1)
(x1,y1),第二个序列
(
x
2
,
y
2
)
(x_2,y_2)
(x2,y2),则有合并后的序列为
(
y
1
+
y
2
,
x
1
+
x
2
)
(y_1+y_2,x_1+x_2)
(y1+y2,x1+x2),则
[
(
2
y
1
+
2
y
2
+
x
1
+
x
2
)
%
3
+
(
2
x
1
+
y
1
)
%
3
+
(
2
x
2
+
y
2
)
%
3
=
[
3
(
x
1
+
x
2
+
y
1
+
y
2
)
]
%
3
]
%
3
=
0
⇒
[
(
2
y
1
+
2
y
2
+
x
1
+
x
2
)
%
3
+
1
+
1
]
%
3
=
0
⇒
(
2
y
1
+
2
y
2
+
x
1
+
x
2
)
%
3
=
1
[(2y_1+2y_2+x_1+x_2)\%3+(2x_1+y_1)\%3+(2x_2+y_2)\%3=[3(x_1+x_2+y_1+y_2)]\%3]\%3=0\Rightarrow [(2y_1+2y_2+x_1+x_2)\%3+1+1]\%3=0\Rightarrow (2y_1+2y_2+x_1+x_2)\%3=1
[(2y1+2y2+x1+x2)%3+(2x1+y1)%3+(2x2+y2)%3=[3(x1+x2+y1+y2)]%3]%3=0⇒[(2y1+2y2+x1+x2)%3+1+1]%3=0⇒(2y1+2y2+x1+x2)%3=1。即合并后的序列仍然满足该性质。最开始的时候每个序列都为
(
0
,
1
)
(0,1)
(0,1),显然满足
(
2
x
+
y
)
%
3
=
1
(2x+y)\%3=1
(2x+y)%3=1,因此最终合并出来的答案也满足
(
2
x
+
y
)
%
3
=
1
(2x+y)\%3=1
(2x+y)%3=1。
也就是说我们只要枚举可能的满足上述条件的 { b i } \{b_i\} {bi}序列,然后计算答案取最大值即可。
不过可惜上述条件只是必要条件,考虑一个反例 1 , − 1 , 1 , − 1 , . . 1,-1,1,-1,.. 1,−1,1,−1,..,也就是正负一交替的情况,这种情况不能出现,因为我们合并的最开始的两个数最后的符号一定相同,并且这两个数相邻,这与反例的情况不符。
因此我们需要枚举的 { b i } \{b_i\} {bi}序列需要满足:1. ( 2 x + y ) % 3 = 1 (2x+y)\%3=1 (2x+y)%3=1。2.存在相邻项符号相同。
直接枚举 { b i } \{b_i\} {bi}不太行,于是考虑 d p dp dp,设 d p [ i ] [ j ] [ k ] [ h ] dp[i][j][k][h] dp[i][j][k][h]表示考虑到前 i i i位,满足 ( 2 x + y ) % 3 = j (2x+y)\%3=j (2x+y)%3=j, b i = { − 1 i f k = 0 1 i f k = 1 b_i=\begin{cases}-1&if\;k=0\\1&if\;k=1\end{cases} bi={−11ifk=0ifk=1, [ h = 1 ] = [ 是 否 存 在 相 邻 项 符 号 相 同 ] [h=1]=[是否存在相邻项符号相同] [h=1]=[是否存在相邻项符号相同]情况的序列最大值。
转移方程也很好写,具体参照代码即可。
ll a[maxn],dp[maxn][3][2][2];
int main(){
int n=rd();
FOR(i,1,n+1)a[i]=rd();
if(n==1)return wrn(a[1]),0;
memset(dp,-0x3f,sizeof(dp));
dp[1][2][0][0]=-a[1];
dp[1][1][1][0]=a[1];
FOR(i,1,n){
FOR(j,0,3){
FOR(l,0,2)
FOR(k,0,2){
dp[i+1][(j+2)%3][0][k|(l==0)]=max(dp[i+1][(j+2)%3][0][k|(l==0)],dp[i][j][l][k]-a[i+1]);
dp[i+1][(j+1)%3][1][k|(l==1)]=max(dp[i+1][(j+1)%3][1][k|(l==1)],dp[i][j][l][k]+a[i+1]);
}
}
}
printf("%lld\n",max(dp[n][1][1][1],dp[n][1][0][1]));
}