• 【算法•日更•第十七期】信息奥赛一本通1598:【 例 2】最大连续和题解


      废话不多说,直接上题:


    1598:【 例 2】最大连续和


    时间限制: 1000 ms         内存限制: 524288 KB
    提交数: 303     通过数: 91 

    【题目描述】

    给你一个长度为 n 的整数序列 {A1,A2,,An},要求从中找出一段连续的长度不超过 m 的子序列,使得这个序列的和最大。

    【输入】

    第一行为两个整数 n,m;

    第二行为 n 个用空格分开的整数序列,每个数的绝对值都小于 1000。

    【输出】

    仅一个整数,表示连续长度不超过 m 的最大子序列和。

    【输入样例】

    6 4
    1 -3 5 1 -2 3

    【输出样例】

    7

    【提示】

    数据范围与提示:

    对于 50% 的数据,1≤N,M≤104 ;

    对于 100% 的数据,1N,M2×105 。

    【来源】


      这道题明显和例一一样。都要用到单调队列优化动态规划,不过也有很多方法,我们来讲一讲。

      方法1:暴力

      用普通单调队列优化的方法,将k从1枚举到m。

      方法2:优先队列优化

      时间复杂度依旧很高。

      方法3:单调队列优化

      我们可以维护一个前缀和。那么这个前缀和是干什么的呢?我们可以依次来差分。

      我们需要维护一个i-k ~ i+1的区间(长度为m),找到一个最小的前缀和(这样就可以保证这个区间内的和最大),用pre[i+1]-这个前缀和就是这个区间的最大值了,那么用ans来记录一下最大值即可。

      同时要注意一个细节:看到别人的博客都有这样一句话if(n<=m) ans=max(ans,pre[n]);,这是为什么呢?当n=4,k=6时,数字分别是1,1,1,1,这种情况应该输出4,但是程序会输出3,这是为什么呢?因为队列一定不会是空的,也就是说一定会减去1,那么答案就错了。

      

      好了,详见注释,代码如下:

      

     1 #include<iostream>
     2 using namespace std;
     3 int n,m,a[1000000],num[1000000],q[1000000],pre[1000000],ans;
     4 inline void dp()
     5 {
     6     int head=1,tail=0;//标志队列为空 
     7     ans=pre[1];
     8     if(n<=m) ans=max(ans,pre[n]);//特判 
     9     for(int i=1;i<n;i++)//常规操作 
    10     {
    11         while(num[head]<i-m+1&&head<=tail) head++;
    12         while(pre[num[tail]]>=pre[i]&&head<=tail) tail--;
    13         num[++tail]=i;
    14         ans=max(ans,pre[i+1]-pre[num[head]]);//记录ans 
    15     }
    16 }
    17 int main()
    18 {
    19     cin>>n>>m;
    20     for(int i=1;i<=n;i++)
    21     {
    22         cin>>a[i];
    23         pre[i]=pre[i-1]+a[i];//记录前缀和 
    24     }
    25     dp();
    26     cout<<ans;
    27     return 0;
    28 }
  • 相关阅读:
    javascript:;与javascript:void(0);
    visual studio 扩展插件
    大数据大规律
    由浅入深理解express源码(四)
    由浅入深理解express源码(三)
    由浅入深理解express源码(二)
    由浅入深理解express源码(一)
    mac链接linux终端,shell脚本发布代码
    Mac nginx 配置
    js正则表达式之解析——URL的正则表达式
  • 原文地址:https://www.cnblogs.com/TFLS-gzr/p/11213724.html
Copyright © 2020-2023  润新知