最大子段和及其拓展

1、最大子段和问题

问题定义对于给定序列a1,a2,a3……an,寻找它的某个连续子段,使得其和最大(如果某子序列全是负数则定义该子段和为 0)。如( -2,11,-4,13,-5,-2 )最大子段是{ 11,-4,13 }其和为20。

·状态设计

dp[i] (1 <= i <= N) 表示以 a[i] 结尾的最大连续子段和。

显然,dp[i] >= 0 (1 <= i <= N)

状态转移方程:dp[i] = max{dp[i-1] + a[i], 0} (2 <= i <= N)

(每个a[i]有两个决策:加入以a[i-1]为结尾的最大连续子段;重新开始一个子串)

下面是http://blog.csdn.net/niteip/article/details/7444973

的证明:

主要讨论这个问题的建模过程和子问题结构.时刻记住一个前提,这里是连续的区间

  • 令b[j]表示以位置 j 为终点的所有子区间中和最大的一个
  • 子问题:如j为终点的最大子区间包含了位置j-1,则以j-1为终点的最大子区间必然包括在其中
  • 如果b[j-1] >0, 那么显然b[j] = b[j-1] + a[j],用之前最大的一个加上a[j]即可,因为a[j]必须包含
  • 如果b[j-1]<=0,那么b[j] = a[j] ,因为既然最大,前面的负数必然不能使你更大

对于这种子问题结构和最优化问题的证明,可以参考算法导论上的“剪切法”,即如果不包括子问题的最优解,把你假设的解粘帖上去,会得出子问题的最优化矛盾.证明如下

  • 令a[x,y]表示a[x]+…+a[y] , y>=x
  • 假设以j为终点的最大子区间 [s, j] 包含了j-1这个位置,以j-1为终点的最大子区间[ r, j-1]并不包含其中
  • 即假设[r,j-1]不是[s,j]的子区间
  • 存在s使得a[s, j-1]+a[j]为以j为终点的最大子段和,这里的 r != s
  • 由于[r, j -1]是最优解, 所以a[s,j-1]<a[r, j-1],所以a[s,j-1]+a[j]<a[r, j-1]+a[j]
  • 与[s,j]为最优解矛盾.

2.最大子矩阵

合并列上的数值,即可转化为一维的最大子段和问题

3.M子段和

未完待续

时间: 2024-11-05 03:57:09

最大子段和及其拓展的相关文章

动态规划POJ专题

声明:本文属博主原创文章,未经允许请勿转载. 经典题目题号(此处为转载):容易: 1018, 1050, 1083, 1088, 1125, 1143, 1157, 1163, 1178, 1179, 1189, 1191,1208, 1276, 1322, 1414, 1456, 1458, 1609, 1644, 1664, 1690, 1699, 1740, 1742, 1887, 1926, 1936, 1952, 1953, 1958, 1959, 1962, 1975, 1989, 

Spoj 2916 Can you answer these queries V 线段树 求任意重叠区间的最大子段和

题目链接:点击打开链接 题意: T个测试数据 n个数字 q个询问 每个询问 : [x1, y1] [x2, y2] 问: int ans = -inf; for(int i = x1; i <= y1; i++) for(int j = max(x2, i); j <= y2; j++) ans = max(ans, query(i, j)); 思路: query_L(int l, int r) 求的是在区间[l,r]内 ,左端点为l的最大子段和. 其他和GSS3差不多. 分类讨论一下给定的区

[C++]用三种方法求最大子段和

问题描述:给定n个整数组成的序列,求其中子段和的最大值.当所有整数均为非负整数时定义其最大子段和为0 方法一:O(n2)用一个值存储最大和,用枚举所有和的方法,来与这个值比较并更新最大值. 1 int MaxSum(int n, int *a, int &besti, int &bestj) 2 { 3 int sum=0; 4 for(int i=0;i<n;++i) 5 { 6 int parts=0; 7 for(int j=i;j<n;++j) 8 { 9 parts+

js算法集合(一) 水仙花数 及拓展(自幂数的判断)

js算法集合(一) ★ 最近有些朋友跟我说对js中的一些算法感到很迷惑,知道这个算法到底是怎么回事,但是就是不会用代码把它写出来,这里我跟大家分享一下做水仙花数的算法的思路,并对其扩展到自幂数的算法,希望能对大家有所帮助. 1.验证一个数是否为水仙花数 ①要写水仙花数的算法,我们首先来了解一下什么是水仙花数,水仙花数是指一个 3位正整数 ,它的每个位上的数字的 3次幂之和等于它本身.(例如:1^3 + 5^3+ 3^3 = 153): ②了解了什么是水仙花数我们就开始分析该怎么下手.通过定义来看

DNS服务配置及拓展(1)

DNS服务配置及拓展 一.DNS服务的信息说明: A##正向记录 PTR##反向,ip到域名 host -l example.com##查看域中的所有主机 dig -t soa example.com##辅助dns 软件包: bind DNS主配置目录:/var/named/chroot/ DNS主配置文件:/etc/named.conf DNS A记录存放目录:/var/named/chroot/var/named 二.如何配置dns正向解析: 1.vim /etc/named.conf#编辑

《ES6标准入门》29~48Page 字符串拓展 正则拓展

1.字符串的拓展 ES3允许使用类似\u0061这样的形式来表示字符,其中的数字是Unicode-8编码. 但如果超出\uffff的字符,必须使用双字节的形式表达,例如 \uD842\uDFB7. 在ES6中,可以用\u{20BB7}这种形式表示,其中数字是Unicode-16编码. 对于需要Unicode-16编码存储的字符,ES认为有2个字符.此时使用String.codePoinAt()方法,可以准确的识别字符串中的字符,如果需要遍历,则需要使用for...of循环. 与此相对,Strin

es6函数的rest参数和拓展运算符(...)的解析

es6的新特性对函数的功能新增加了rest参数和...的拓展运算符.这是两个什么东西呢? 先来看一个问题:如何获取一个函数除了定义的参数之外的其他参数?传统的做法是借助函数的arguments关键字来获取的. 方法如下: function add(a,b){ var i=2,rest=[]; if(arguments.length>2){ for(i;i<arguments.length;i++){ rest.push(arguments[i]); } } return rest; } con

单片微机原理P3:80C51外部拓展系统

外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC. 0. IO接口电路概念与存储器拓展 1. 为什么需要IO电路?:1. 协调计算机与外设的速度的差异 2. 输入/输出过程中的状态信号 3. 解决计算机信号与外设信号之间不一致 2. IO传送方式三种:1. 无条件传送(灯,DAC),2. 查询,3. 中断(ADC). 3. DMA存储方式(直接传输数据不通过CPU(不需要CPU),这种方式实际上已经

【poj 1061】青蛙的约会(数论--同余方程 拓展欧几里德)

题意:已知2只青蛙的起始位置 a,b 和跳跃一次的距离 m,n,现在它们沿着一条长度为 l 的纬线(圈)向相同方向跳跃.问它们何时能相遇?(好有聊的青蛙 (??????‵) *)永不相遇就输出"Impossible".(蠢得可怜 -_-!) 解法:用拓展欧几里德求同余方程的最小正整数解.(a+mx)-(b+nx)=k*l (k表示圈数) → (m-n)x=k*l+b-a → (m-n)x=b-a(mod l).当然其实=(b-a)%l 更准确,但反正都是模,也没有关系啦.于是就像上题一