动态规划——最大子数组

上一篇我们用分治法已经将问题的复杂度降低了许多,但是,我们依旧不满足,于是,我们尝试用动态规划来做这道题。

解题思路:

对于这样一个连续和的问题(个人习惯叫做最大连续和),如果我们要用动态规划来解,首先得考虑状态和状态转移方程。如果我们把题述数组看成序列,那么是不是可以用序列DP来考虑呢?

我们不妨考虑一个这样的序列:1,-3,5,-2,4

a[i]表示这个序列的第 i 个元素,dp[i]表示最后一个元素是a[i]的最大连续和(此乃状态,是不是跟LIS的DP解法有点类似),于是:

dp[0] : a[0] ; ( 1 )

dp[1] : max(dp[0] + a[1] , a[1]) ; ( -2 )

dp[2] : max(dp[1] + a[2] , a[2]) ; ( 5 )

dp[3] : max(dp[2] + a[3] , a[3]) ; ( 3 )

dp[4] : max(dp[3] + a[4] , a[4]) ; ( 7 )

所以:ans = 7 (dp数组的最大值)

于是,我们可以得到状态转移方程:dp[i+1] = max(dp[i]+a[i+1] , a[i+1])

写成代码的话,我们可以忽略掉dp数组,直接用一个变量sum来记录 i 之前的最大增量(因为如果这个增量为负,则变为0)

wikioi 3155

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f

using namespace std;

int n,ans,sum,a[1000005];

int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);

        ans=~INF,sum=0;
        for(int i=0;i<n;i++)
        {
            sum+=a[i];
            if(ans<sum)
                ans=sum;
            if(sum<0)
                sum=0;
        }
        printf("%d\n",ans);
    }

    return 0;
}

总结:

果然动规很强啊。。。。

时间: 2024-10-24 21:54:58

动态规划——最大子数组的相关文章

动态规划解决“最大子数组”问题

TODO: 动态规划到底是个什么玩艺? ref:http://www.cnblogs.com/waytofall/archive/2012/04/10/2439820.html I 只考虑怎样产生更大的子组和: 假设处理到第i个节点时: 1. 考虑是否i节点是否可使子组的和变大 a) 如果i节点大于0,则最大子组和是前面求到的数组和 加上 i节点值 b) 如果i节点小于0(等于0的话,值可以带上i,也可以不带上i,无所谓),当最大子数组的和是前面求的子组和 2. 然后考虑最大值是否应该更新了 a

[LeetCode] 152. 乘积最大子数组 ☆☆☆(动态规划)

乘积最大子数组 描述 给定一个整数数组 nums ,找出一个序列中乘积最大的连续子数组(该序列至少包含一个数). 示例 1: 输入: [2,3,-2,4]输出: 6解释: 子数组 [2,3] 有最大乘积 6.示例 2: 输入: [-2,0,-1]输出: 0解释: 结果不能为 2, 因为 [-2,-1] 不是子数组. 解析 看起来和连续子数组的最大和类似,一个是和,一个是积. 其实有点不一样.如果当前元素为负数,那么当前元素的字数组最大值是前一个元素的最小值 * 当前元素. 所有,存储前一个元素的

结对开发——返回整数数组最大子数组和2

返回整数数组最大子数组和2 为了实现“敏捷开发”的目的,老师让我们采取“迭代”的方法进行项目的开发,这不,对于周一的求最大子数组和又有了新的要求,如下: 1.延续上次的要求,这里不再赘余… 2.如果数组A[0]……A[j-1]首尾相连,允许A[i-1],……A[n-1],A[0]……A[j-1]之和最大: 3.同时返回最大子数组的位置: 4.要求程序必须能处理1000 个元素,且每个元素是int32 类型的. 一.实验设计思路 首先实现的是数组首尾相连,先存入数组,再将原数组反向存储形成环形数组

最大子数组之和、最大子数组之积、最长递增子序列求法

昨天做爱奇艺笔试题,最后一道编程题是求整型数组最长递增子序列,由于时间关系,没有完全写出来,今天重新来做做这一系列题. <1> 最大子数组之和 首先从最简单的最大子数组之和求取.数组里有正数.负数.零.设包含第 i 个元素的子数组的和为 Sum,则Sum的值为 Sum(i) = Sum(i-1) + arrey[i]; 显然如果arrey[i]<=0,则Sum(i)<=Sum(i-1);则必须把Sum(i)=arrey[i];同时maxSum用来保存Sum最大值.时间复杂度为o(n

(算法)最大子数组和以及最大子矩阵和

题目: 1.给定一数组,求该数组的最大子数组和: 2.给定一矩阵,求该矩阵的最大子矩阵和: 思路: 1.求数组的最大子数组和很简单,可以通过动态规划来实现,假设数组为arr: 假设dp[i]表示从0到i的数组的最大子数组和,那么递推关系式表示为: dp[0]=arr[0]; dp[i]=dp[i-1]>0?dp[i-1]+arr[i]:arr[i] 2.求矩阵的最大子矩阵和看似很难,其实也可以转化为最大子数组和的问题.假设矩阵为matrix 首先,我们求出矩阵每个位置按行叠加的结果,设叠加结果矩

最大子数组和(最大子段和)

比如对于数组[1,-2,3,5,-1,2] 最大子数组和是sum[3,5,-1,2] = 9, 我们要求函数输出子数组和的最大值,并且返回子数组的左右边界(下面函数的left和right参数). 本文我们规定当数组中所有数都小于0时,返回数组中最大的数(也可以规定返回0,只要让以下代码中maxsum初始化为0即可,此时我们要注意-1 0 0 0 -2这种情形,特别是如果要求输出子数组的起始位置时,如果是面试就要和面试官问清楚) 以下代码我们在PAT 1007. Maximum Subsequen

最大子数组之和

返回一个整数数组中最大子数组的和,细化分析: 1,在所有以元素tail结尾的子数组中,选出元素和最大的子数组,tail=1,2...n. 2,以元素k结尾的和最大的子数组是包含以元素tail-1结尾的和最大的子数组还是就只有元素tail这一个元素,一共有这两个可选状态. 3,在得到以每个元素结尾的和最大的子数组之后,只要取其中最大值就是所有子数组中最大的子数组. 团队成员:王硕  http://home.cnblogs.com/u/WS1004/ #include <iostream> #in

求一维数组的最大子数组1(结对开发)

题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n) 发表一篇博客文章讲述设计思想,出现的问题,可能的解决方案(多选).源代码.结果截图.总结. 结对开发的伙伴: 博客名:Mr.缪 姓名:缪金敏 链接:http://www.cnblogs.com/miaojinmin799/ 分析: 如果按照最笨的方法就是一个一个的比较先比较一个数的然后二个

算法导论3:最大子数组问题 2016.1.3

顶着期末复习的压力,还是在今天过完之前看完了一个算法——最大子数组问题. <算法导论>中引入这个问题是通过股票的购买与出售,经过问题转换(转换的过程比较简单,但是不好想),将前一天的当天的股票差价重新表示出来,即转为了一个最大子数组的问题 ,具体内容是:   13, -3, -25, 20, -3, -16, -23, 18, 20, -7, 12, -5, -22, 15, -4, 7   找到这连续的16个数里面的连续和最大的子数组;   书中差不多是这个意思:假定我们要寻找子数组A[lo