cf 1421E. Swedish Heroes (dp)

题目链接:传送门

题目思路:通过观察 题解 规律 ,总结出:

1. 最后的答案 ans  =  Σpi * ai  , pi = { -1 ,1 } ;

 2. 系数集合p满足: 

 

但是有一个特例 p = {1,-1,1,-1,... , 1} ,显然第一次选择两个个数相加,知道最后这两个数字的pi应该是相等的 ;当然 p = {-1 , 1 , -1 , ... , 1 , -1 } 也是不合规则的,但是它不美,满足上述的第二个条件

声明 dp(i,j,k) : 表示 前i个数字 ,-1的个数为j ,是否为特例 的"求和"后最大值 , k=1 表示为特例 ;

i为奇数: dp(i,j,1) <- dp(i-1,j,1) + a[i] , dp(i,j,0) <- dp(i-1,(j+2)%3,1) - a[i];  (0表示不为特例 ,求和得来的最大值,显然必须某位加-1 使得其变成  1 -1 1 -1 -1)

i为偶数: dp(i,j,1) <- dp(i-1,(j+2)%3,1) + a[i] , dp(i,j,0) <- dp(i-1,j,1) + a[i]; (使其变成 1 -1 1 1 )

 dp(i,j,0) <- max{ dp(i,j,0) , dp(i-1,j,0) + a[i] , dp(i-1,(j+2)%3,0) - a[i] } ;

 

代码:

#include<bits/stdc++.h>
/*
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<cctype>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
*/
#pragma GCC optimize(2)
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
typedef pair<double,double> pdd;
const int N=2e5+5;
const int M=8e5+5;
const LL inf=1e17;
const LL mod=1e8+7;
const double eps=1e-5;
const long double pi=acos(-1.0L);
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
    LL x=0,t=1;
    char ch;
    while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
    while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    return x*t;
}
// n + cnt:op=-1 = 1 (mod 3)
LL dp[N][3][2];
LL a[N];
int main()
{
    int n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=n;i++)
        for(int j=0;j<3;j++)
            for(int k=0;k<2;k++)
                dp[i][j][k]=-inf;
    if(n==1) return 0*printf("%lld\n",a[1]);
    dp[1][1][0]=-a[1];//写法2: j表示 -1的个数 取模3 , k 表示 该串是否为 1 -1 1 -1 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;
}
View Code

 

posted @ 2020-10-20 20:09  DeepJay  阅读(207)  评论(0编辑  收藏  举报