[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+0\equiv 1(mod\ 3)$),合並后有仍然滿足這一條件

但並不是滿足這個條件就一定可行,例如$p_{i}=\{1,-1,1,...,1\}$(長度超過1)時滿足但不可行

對於$p_{i}\ne\{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}\ne\{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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM