zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",dp[n][((1-n)%3+3)%3][0]);
        return 0;
    }
    View Code
  • 相关阅读:
    我的暑假周记2018.7.21
    大道至简读后感
    我的暑假周记2018.7.15
    继承与多态
    java联级调用
    古罗马凯撒大帝字串加密
    作业三
    线性同余法产生1000个随机数
    Text2
    java登录界面
  • 原文地址:https://www.cnblogs.com/DeepJay/p/13848595.html
Copyright © 2011-2022 走看看