博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tyvj1305最大子序和(单调队列优化dp)
阅读量:5040 次
发布时间:2019-06-12

本文共 1100 字,大约阅读时间需要 3 分钟。

描述

输入一个长度为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

备注

数据范围:
100%满足n,m<=300000
 
是不超过m,不是选m个!!!!!
/*单调队列优化dp单调队列维护的是前缀和的递增序列更新答案的时候从对首开始找第一个区间在m范围内的f[i]表示到第i个数的不超过m的最大连续子段和,sum[i]表示i的前缀和f[i]=max(sum[i]-sum[k])(i=> k >=i-m),所以要找最小的sum[k],因此用单调队列。 */#include
#include
using namespace std;int n,m,tot,head,tail,x,k; struct node{ int v,u; //v代表值,u代表下标用来判断是否超过m }q[100001]; int main() { scanf("%d%d",&n,&m); scanf("%d",&tot);//第一个元素 head=1;tail=2; q[head].v=tot;q[head].u=1; k=tot; for(int i=2;i<=n;i++) { scanf("%d",&x); tot+=x; while(q[tail-1].v>=tot && tail-1>=head) tail--;//队列中只有一个元素且比当前和大,更新 q[tail].v=tot; q[tail].u=i;//记录下标 tail++; if(i-q[head].u>m) head++;//确定区间m if(tot-q[head].v>k) k=tot-q[head].v; //更新答案 } printf("%d\n",k); return 0; }

 

转载于:https://www.cnblogs.com/L-Memory/p/6361377.html

你可能感兴趣的文章
剑指 offer set 2 从头到尾打印链表
查看>>
博客开通第69天
查看>>
博客开通第九天
查看>>
Java7/8 中的 HashMap 和 ConcurrentHashMap 全解析
查看>>
8086中的七种寻址方式
查看>>
秒杀系统解决方案
查看>>
Java动态代理机制
查看>>
【Git】Git工具常用命令
查看>>
ipmsg 绑定tcp错误
查看>>
九型人格判定
查看>>
NOPI读取模板导出(Excel中追加数据)
查看>>
linux mail 命令参数
查看>>
JAVA防盗链在报表中的应用实例
查看>>
Windows Azure Web Site (11) 使用源代码管理器管理Azure Web Site
查看>>
【转】Xcode托管代码到oschina中的教程
查看>>
python基于matplotlib绘图
查看>>
Gvim编码学习笔记
查看>>
IsPostBack
查看>>
android 网络语音电话合集 此文为转载备份
查看>>
hdu 5071 vector操作恶心模拟
查看>>