动态规划-最大子段和其变式

最大子段和

给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。

O(n3) :枚举左右端点,再进行 O(n) 求和。

O(n2) :同上,求和使用前缀和优化 O(1) 查询。

O(n) : DP写法//
模拟求最大子段和的过程,从左到右顺序遍历,从第一个数开始考虑,考虑到第1个数时,此时以1为结尾最大子段和为a[1]。考虑第二个数如果a[1]+a[2]>a[2],此时以2为结尾的最大子段和是a[1]+a[2],如果a[1]+a[2]<a[2],此时以2为结尾的最大子段和是a[2]。

状态:所以我们可以顺序遍历,考虑以i为结尾的子段,是自己自创门派还是和邻居一起会获得更优的结果。因此我们可以设计状态为 f[i]为结尾,获得的最大连续子段和。
转移:

  1. a[i]+f[i-1]>a[i] 和邻居合伙的收益更大。f[i]=a[i]+f[i1]
  2. a[i]+f[i-1]<a[i] 自创门派的收益更大 f[i]=a[i]
  3. a[i]+f[i-1]=a[i] 收益好像一样,那该怎么?其实加不加上没影响。如果加上的话就可以。连接两段,使你的最大子段和更长。

长度等于、大于、小于k的最大子段和

暴力算法同上

等于:O(n) 单调队列,顺序遍历,求出 i-m+1 到 i 子段和,维护最大子段和。

大于:O(nm) 单调队列,顺序遍历,枚举kk<im+1求出 k 到 i子段和,维护最大子段和。

小于:O(nm) 单调队列,顺序遍历,枚举kim+1<k<=i求出 i 到 k子段和,维护最大子段和。

环状最大子段和

处理环型的问题都有一个通用的解法 将数据复制一份在末尾,环的问题就变成的普通的链的问题。

最大两端子段和

O(n) 考虑枚举两端和中间的空点,只需要求出 空点左侧的子段最大和和空点右侧的子段最大和,再维护两端最大和即可。空点左右侧的最大和,可以通过预处理的得到。


参考文献

  1. 题解 P1115 【最大子段和】by_Arahc_
  2. P1121 环状最大两段子段和 题解 byDevelop

作者:wh1sky

出处:https://www.cnblogs.com/wh1sky/p/18003388

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Wh1sky  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示