zoukankan      html  css  js  c++  java
  • [cf1421E]Swedish Heroes

    令$p_{i}$为最终$a_{i}$之前的系数($p_{i}in {-1,1}$),则有$n+sum_{i=1}^{n}[p_{i}=-1]equiv 1(mod 3)$

    证明:对于两个满足这一条件的区间(初始$1+0equiv 1(mod 3)$),合并后有仍然满足这一条件

    但并不是满足这个条件就一定可行,例如$p_{i}={1,-1,1,...,1}$(长度超过1)时满足但不可行

    对于$p_{i} e{1,-1,1,...,1}$,则其一定可以被拆成两段,使得都满足$n+sum_{i=1}^{n}[p_{i}=-1]equiv 2(mod 3)$(取反后即模3余1),然后分类讨论:

    1.两段中没有${1,-1,1,...,1}$,通过归纳法可以证明一定可行;

    2.两端中有一段(可以有2段)是${1,-1,1,...,1}$,不妨假设第二段是,那么可以将分割点+2,不改变两边对于3的模数,直至划分为$[1,n-1]$和$[n,n]$,同样可以用归纳法来证明

    通过这些,我们就证明了对于$p_{i} e{1,-1,1,...,1}$,都一定可行

    根据这一性质,设$f[i][j]$表示前$i$个数,$-1$的个数模3余$j$,强制前$i$个位置中与${1,-1,1,...,1}$不同的最大值,转移考虑不同的位置即可,答案即$f[n][(1-n)%3]$

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 200005
     4 int n,a[N];
     5 long long sum[N],f[N][3];
     6 int main(){
     7     scanf("%d",&n);
     8     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
     9     if (n==1){
    10         printf("%d",a[1]);
    11         return 0;
    12     }
    13     for(int i=1;i<=n;i++)
    14         if (i&1)sum[i]=sum[i-1]+a[i];
    15         else sum[i]=sum[i-1]-a[i];
    16     f[1][1]=-a[1];
    17     f[1][0]=f[1][2]=-1e16;
    18     for(int i=2;i<=n;i++){
    19         for(int j=0;j<3;j++)f[i][j]=-1e16;
    20         if (i&1)f[i][(i+1)/2%3]=sum[i-1]-a[i];
    21         else f[i][(i-1)/2%3]=sum[i-1]+a[i];
    22         for(int j=0;j<3;j++)f[i][j]=max(f[i][j],max(f[i-1][j]+a[i],f[i-1][(j+2)%3]-a[i]));
    23     }
    24     printf("%lld",f[n][(N-3-n)%3]);
    25 }
    View Code
  • 相关阅读:
    phonegap helloworld 之android
    perl 信号
    css的浮动
    css的定位
    p4 环境变量的优先级
    oracle sql 高级
    perl数组高级
    让你提升命令行效率的 Bash 快捷键 [完整版]
    函数的返回值为结构体类型
    函数的返回值保存在内存的什么区域
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13838685.html
Copyright © 2011-2022 走看看