E12 单调队列 连续子序列的最大和
视频链接:https://www.bilibili.com/video/BV1m54y117uu/
E11【模板】单调队列 滑动窗口最值 - 董晓 - 博客园 (cnblogs.com)
f[i]表示选第 i 个数,且长度不超过m的最大连续和
f[i] = max(s[i]-s[j]) = s[i]-min(s[j]), i-m<=j<=i-1,s为前缀和
#include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N=300010; int n, m; int s[N], f[N], q[N]; int main(){ scanf("%d%d", &n, &m); for(int i=1; i<=n; i++) scanf("%d",&s[i]),s[i]+=s[i-1]; //前缀和 int h=1, t=0; //清空队列 for(int i=1; i<=n; i++){ //枚举序列 while(h<=t && s[q[t]]>=s[i-1]) t--; //队尾出队(队列不空且新元素更优) q[++t]=i-1; //队尾入队(存储下标 方便判断队头出队) if(q[h]<i-m) h++; //队头出队(队头元素滑出窗口) f[i]=s[i]-s[q[h]]; //更新答案 } int res=-2e9; for(int i=1; i<=n; i++)res=max(res,f[i]); printf("%d\n", res); }
#include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N=300010; int n, m; int s[N], f[N], q[N]; int main(){ scanf("%d%d", &n, &m); for(int i=1; i<=n; i++) scanf("%d",&s[i]),s[i]+=s[i-1]; //前缀和 int h=1, t=0; //清空队列 for(int i=1; i<=n; i++){ //枚举序列 while(h<=t && q[h]<i-m) h++; //队头出队(队列不空且队头元素滑出窗口) while(h<=t && s[q[t]]>=s[i-1]) t--; //队尾出队(队列不空且新元素更优) q[++t]=i-1; //队尾入队(存储下标 方便判断队头出队) f[i]=s[i]-s[q[h]]; //更新答案 } int res=-2e9; for(int i=1; i<=n; i++)res=max(res,f[i]); printf("%d\n", res); }
练习
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!