Loj-10176-最大连续和
题目
测试得分: 100
主要算法 : 单调队列优化DP
题干:
单调队列优化DP板子
题意分析错误,但是有部分分
/*
这个代码使用滚动数组优化的暴力,有局限性,只能处理长度为m区间的最大连续和,而并不是小于等于m的
#include<stdio.h> #include<stdlib.h> #define FORa(i,s,e) for(int i=s;i<=e;i++) #define FORs(i,s,e) for(int i=s;i>=e;i--) #define gc getchar()//pa==pb&&(pb=(pa=buf)+fread(buf,1,100000,stdin),stdin)?EOF:*pa++ #define File(name) freopen(name".in","r",stdin);freopen(name".out","w",stdout); using namespace std; char buf[100000],*pa,*pb; inline int read(); const int K=2*1e5,INF=2147483647; int a,n,k,ans=-INF,sum[K+1]; inline int max(int fa,int fb){return fa>fb?fa:fb;} int main() { File("1"); n=read(),k=read(); FORa(i,1,n) { a=read(); sum[i%(k+1)]=sum[(i-1)%(k+1)]+a; if(i>=k) ans=max(ans,sum[i%(k+1)]-sum[(i-k)%(k+1)]); } printf("%d",ans); return 0; } inline int read() { register char c(gc);register int f(1),x(0); while(c<'0'||c>'9') f=c=='-'?-1:1,c=gc; while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=gc; return x*f; } */
单调队列优化动规
#include<stdio.h> #include<stdlib.h> #define FORa(i,s,e) for(int i=s;i<=e;i++) #define FORs(i,s,e) for(int i=s;i>=e;i--) #define File(name) freopen(name".in","r",stdin);freopen(name".out","w",stdout); using namespace std; const int N=2*1e5,INF=2147483647; int n,k,s[N+7],q[N+7],head=1,tail=0,ans=-INF; /*将合法元素塞入容量为m的单调队列中, 如果现在这个比当前队列中后面较为劣的元素要好,删除比它劣的元素 */ inline int max(int fa,int fb){return fa>fb?fa:fb;} int main() { scanf("%d%d",&n,&k); FORa(i,1,n) scanf("%d",&s[i]),s[i]+=s[i-1]; FORa(i,1,n) { while(head<=tail&&s[q[tail]-1]>=s[i-1]) tail--;//如果现在这个比当前队列中后面较为劣的元素要好,删除比它劣的元素 q[++tail]=i;//插入该元素,原理是这个元素必须要选 while(head<=tail&&q[head]<i-k+1) head++; ans=max(ans,s[i]-s[q[head]-1]); } printf("%d",ans); }