首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【题解】数列求和

【题解】数列求和

作者头像
MikeC
发布于 2022-09-21 11:43:16
发布于 2022-09-21 11:43:16
6370
举报
文章被收录于专栏:MikeC's BlogMikeC's Blog

题目描述

给定 N 个正整数组成的数列 a_1, a_2, \cdots, a_n 和一个整数 m。求出这个数列中的一个子区间 [i, j],也就是在这个数列中连续的数字 a_i, a_{i + 1}, \cdots, a_{j - 1}, a_j,使得这个子区间的和在不超过 M 的情况下最大。如果有多个区间符合要求,请输出 i 最小的那一个。

输入格式

输入共两行。

第一行,两个整数 N,M;

第二行,N 个整数 a_1, a_2, \cdots, a_n。

输出格式

一行,三个整数,表示符合题意的区间的左端点、右端点和累加和。

输入输出样例

输入 #1

代码语言:javascript
复制
5 10
2 3 4 5 6

输出 #1

代码语言:javascript
复制
1 3 9

分析

可以很容易的想到从大到小枚举子区间,但无奈复杂度过高,便可以想到利用前缀和来优化,复杂度大约O(n^2),仍然过不了大数据。于是我们重新观察题目,发现两个端点都不是固定的且它们之间有种奇妙的联系,很轻松就可以想到用双指针优化来进一步减少我们的算法复杂度。

代码

代码语言:javascript
复制
#include<bits/stdc++.h>
using namespace std;
int n,m,a[4000001],ans_l,ans_r,ans,l=1,r=1,q[4000001];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        q[i]=q[i-1]+a[i];
    }
    while(r<=n){
        while(q[r]-q[l-1]>m&&l<=r)l++;
        if(q[r]-q[l-1]>ans){
            ans=q[r]-q[l-1];
            ans_l=l,ans_r=r;
        }
        r++;
    }
    printf("%d %d %d",ans_l,ans_r,ans);
    return 0;
}

最后修改:2021 年 07 月 20 日 03 : 06 PM

© 允许规范转载

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021 年 02 月,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 题目描述
  • 输入格式
  • 输出格式
  • 输入输出样例
    • 输入 #1
    • 输出 #1
  • 分析
  • 代码
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档