Codeforces 1421 E. Swedish Heroes(线性DP,规律)

While playing yet another strategy game, Mans has recruited 𝑛 Swedish heroes, whose powers which can be represented as an array 𝑎.

Unfortunately, not all of those mighty heroes were created as capable as he wanted, so that he decided to do something about it. In order to accomplish his goal, he can pick two consecutive heroes, with powers 𝑎𝑖 and 𝑎𝑖+1, remove them and insert a hero with power −(𝑎𝑖+𝑎𝑖+1) back in the same position.

For example if the array contains the elements [5,6,7,8], he can pick 6 and 7 and get [5,−(6+7),8]=[5,−13,8].

After he will perform this operation 𝑛−1 times, Mans will end up having only one hero. He wants his power to be as big as possible. What’s the largest possible power he can achieve?

Input
The first line contains a single integer 𝑛 (1≤𝑛≤200000).

The second line contains 𝑛 integers 𝑎1,𝑎2,…,𝑎𝑛 (−109≤𝑎𝑖≤109) — powers of the heroes.

Output
Print the largest possible power he can achieve after 𝑛−1 operations.

Examples
inputCopy
4
5 6 7 8
outputCopy
26
inputCopy
5
4 -5 9 -2 1
outputCopy
15
Note
Suitable list of operations for the first sample:

[5,6,7,8]→[−11,7,8]→[−11,−15]→[26]

题意:
一个长度为 n n n的序列,每次选择相邻两个数合并成 − ( x + y ) -(x+y) (x+y),求最后合并成的一个数最大是多少。

思路:
结论是最后的序列会满足 ( n + c n t : o p = − 1 ) m o d    3 = 1 (n+cnt:op=-1)\mod3=1 (n+cnt:op=1)mod3=1。(反正我是没想出来)
特例是 + − + − + . . . + +-+-+...+ +++...+这样的序列,因为初始合并的两个数,最后无论怎么变换符合都会相同,所以一定会出现相邻两个相同符号。

证明:
n = 1 n=1 n=1的时候满足条件
( n 1 + x 1 ) m o d    3 = 1 (n1+x1)\mod3=1 (n1+x1)mod3=1
( n 2 + x 2 ) m o d    3 = 1 (n2+x2)\mod3=1 (n2+x2)mod3=1
( n 1 + x 1 + n 2 + x 2 ) m o d    3 = 2 (n1+x1+n2+x2)\mod3=2 (n1+x1+n2+x2)mod3=2
两个序列合并后的结果为:
( n 1 + n 1 − x 1 + n 2 + n 2 − x 2 ) m o d    3 = ? (n1+n1-x1+n2+n2-x2)\mod3=? (n1+n1x1+n2+n2x2)mod3=?
则合并序列可以得到 ( 3 ∗ n 1 + 3 ∗ n 2 ) m o d    3 = 0 = ? + 2 (3*n1+3*n2)\mod3=0=?+2 (3n1+3n2)mod3=0=?+2
所以 ? = 1 ?=1 ?=1
所以最后序列的结果满足 ( n + c n t : o p = − 1 ) m o d    3 = 1 (n+cnt:op=-1)\mod3=1 (n+cnt:op=1)mod3=1

那么这个问题变成了有限制的线性dp,定义 d p [ i ] [ 0 / 1 / 2 ] [ 0 / 1 ] dp[i][0/1/2][0/1] dp[i][0/1/2][0/1]代表选到了第 i i i个数, c n t : o p = − 1 m o d    3 cnt:op=-1\mod3 cnt:op=1mod3等于多少,这个序列是否是受限制的序列。

然后对于限制序列和非限制序列分别讨论就好了。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include <cstring>

using namespace std;

typedef long long ll;

const int maxn = 2e5 + 7;

int a[maxn];
ll dp[maxn][3][2];

int main() {
    int n;scanf("%d",&n);
    for(int i = 1;i <= n;i++) {
        scanf("%d",&a[i]);
    }
    memset(dp,0xcf,sizeof(dp));
    if(n == 1) {
        printf("%d\n",a[1]);
        return 0;
    }
    dp[1][1][0] = -a[1];
    dp[1][0][1] = a[1];
    
    for(int i = 2;i <= n;i++) {
        for(int j = 0;j < 3;j++) {
            if(i & 1) {
                dp[i][j][1] = dp[i - 1][j][1] + a[i];
                dp[i][j][0] = dp[i - 1][(j + 2) % 3][1] - a[i];
            } else {
                dp[i][j][1] = dp[i - 1][(j + 2) % 3][1] - a[i];
                dp[i][j][0] = dp[i - 1][j][1] + a[i];
            }
            dp[i][j][0] = max(dp[i][j][0],dp[i - 1][j][0] + a[i]);
            dp[i][j][0] = max(dp[i][j][0],dp[i - 1][(j + 2) % 3][0] - a[i]);
        }
    }
    
    printf("%lld\n",dp[n][((1 - n) % 3 + 3) % 3][0]);
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值