列表

详情


NC50971. 最大子序和

描述

输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大。
例如 1,-3,5,1,-2,3
当m=4时,S=5+1-2+3=7
当m=2或m=3时,S=5+1=6

输入描述

第一行两个数n,m
第二行有n个数,要求在n个数找到最大子序和

输出描述

一个数,数出他们的最大子序和

示例1

输入:

6 4
1 -3 5 1 -2 3

输出:

7

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 41ms, 内存消耗: 2704K, 提交时间: 2023-07-26 14:55:59

#include<bits/stdc++.h>
using namespace std;
long long q[1000001],s[1000001];
int main(){
	long long x,n,l=1,r=1,m,ans=0;scanf("%lld%lld",&n,&m);q[1]=0;
	for(register int i=1;i<=n;++i)scanf("%lld",&x),s[i]=s[i-1]+x;
	for(register int i=1;i<=n;++i){
		while(l<=r&&q[l]<i-m)++l;
		ans=max(ans,s[i]-s[q[l]]);
		while(l<=r&&s[q[r]]>=s[i])--r;
		q[++r]=i;
	}
	printf("%lld",ans);
}

C++14(g++5.4) 解法, 执行用时: 114ms, 内存消耗: 2664K, 提交时间: 2020-01-23 15:11:16

#include<iostream>
#include<cstdio>
using namespace std;
long long sum[300010],ans;
int a,n,m,s[300010],l=1,r=1;
int main() {
	cin>>n>>m;
	for(int i=1; i<=n; i++) {
		cin>>a;
		sum[i]=sum[i-1]+a;
		while(l<=r&&s[l]<i-m) l++;
		ans=max(ans,sum[i]-sum[s[l]]);
		while(sum[s[r]]>=sum[i]&&r>=l) r--;
		s[++r]=i;
	}
	cout<<ans;
	return 0;
}

C++(clang++ 11.0.1) 解法, 执行用时: 80ms, 内存消耗: 2732K, 提交时间: 2022-09-20 21:53:30

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int a[N],s[N];
int main()
{
	int n,m,mx=0,l=1,r=1;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[i]+=a[i-1];
		while(l<=r&&s[l]<i-m)l++;
		mx=max(mx,a[i]-a[s[l]]);
		while(a[s[r]]>=a[i]&&r>=l)r--;
		s[++r]=i;
	}
	cout<<mx<<'\n';
	return 0;
}

Python3 解法, 执行用时: 532ms, 内存消耗: 33364K, 提交时间: 2023-07-20 21:21:34

n,m=map(int,input().split())
arr=list(map(int,input().split()))
res=[]
ans=0
pre=[0]
for it in arr: pre.append(it+pre[-1])
for i in range(n+1):
    while res and res[0]+m<i: res.pop(0)
    if res: ans=max(ans,pre[i]-pre[res[0]])
    while res and pre[res[-1]]>pre[i]: res.pop()
    res.append(i)
print(ans)

上一题