[cf1421E]Swedish Heroes

pi为最终ai之前的系数(pi{1,1}),则有n+i=1n[pi=1]1(mod 3)

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

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

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

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

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

通过这些,我们就证明了对于pi{1,1,1,...,1},都一定可行

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

复制代码
 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
复制代码

 

posted @   PYWBKTDA  阅读(584)  评论(3编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示