动态规划法解最大子数组问题

分治法https://www.cnblogs.com/zuofaqi/p/9678356.html 引入了最大子数组问题,它有一个更高效的解决方法就是动态规划法

如果已经直到 A[0...i] 的最大子数组,那么 A[0...i+1] 的最大子数组要么是 A[0...i] 的最大子数组,要么是某个子数组 A[j...i+1] (0<= j <= i+1)

动态规划三要素:

1. 边界:当数组中只有一个元素的时候,最大子数组就是自身

2. 最优子结构:A[0...i+1] 的最优子结构是 A[0...i] 和 A[j...i+1]

3. 状态转移方程:max_arr(A[0...i+1]) = max(A[0...i], A[j...i+1])

根据这个思路,就可以写出代码了

double max_arr(double* arr, int index, int& low, int& high)
{
    if (0 == index)
    {
        low = high = 0;
        return arr[0];
    }

    int pre_low, pre_high;
    double pre_sum = max_arr(arr, index-1, pre_low, pre_high);

    // 找 A[j...i+1]中最大的一个
    double maxsum = arr[index] - 1;
    for (int i = index; i >= 0; i--)
    {
        double cursum = 0;
        for (int j = index; j >= i; j--)
        {
            cursum += arr[j];
        }
        if (cursum > maxsum)
        {
            maxsum = cursum;
            low = i;
        }
    }

    // 比较两个最优子结构的数组和,取最大的一个
    if (maxsum > pre_sum)
    {
        high = index;
        return maxsum;
    }
    else
    {
        low = pre_low;
        high = pre_high;
        return pre_sum;
    }
}

原文地址:https://www.cnblogs.com/zuofaqi/p/9683727.html

时间: 2024-10-01 21:22:34

动态规划法解最大子数组问题的相关文章

最大子数组问题全解

问题描述 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和. 问题解析 很经典的一个问题,下面给出3种解法,暴力解法.分治算法.动态规划.这个题Leetcode上有大量测试数据,只不过最后两个测试数据要求算法复杂度为n,只能用动态规划来解,可以借鉴一下,链接见这里https://leetcode.com/problems/maximum-subarray/description/ 问题解决 1.暴力解法 穷举所有的子串,计算他们的和,然后从中找出最大的一个. //最大子数组的暴力解法

分治策略 &nbsp; 最大子数组问题

递归式 递归式与分治方法是紧密相关的,因为使用递归式可以很自然地刻画分治算法的运行时间.一个递归式就是一个等式或不等式,它通过更小的输入上的函数值来描述一个函数.例如,在2.3.2节,我们用递归式描述了MERGE-SORT过程的最坏情况运行时间T(n): Θ(1)        若n=1 T(n) =                         (4.1) 2T(n/2)+Θ(n)    若n>1 求解可得T(n)=Θ(nlgn) 递归式可以有很多形式.例如,一个递归算法可能将问题划分为规模

一维数组头尾相连求最大子数组

题目: 返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 1. 设计思想: 因为已经写过了一维数组的求最大子数组程序.所以只是在原程序上进行修改.首先产生随机数数组,然后进行计算,因为要求时间复杂度

编程之美4:那些常被考到的关于数组的最大子数组问题

楼主这篇文章的目的是要带大家梳理一下,有关于求子数组问题.如求子数组的最大和,求最大和的子数组,求最大积的子数组等一系列问题.今天阳光明媚,楼主今天心情很好哦,愿大家开心每一天,哈哈.Are you ready?开始了哦~~~ 题目一:求子数组的最大和 题目求子数组的最大和,这里需要注意的一个问题就是,子数组那么便意味着是连续的一段数据.我们可以先写的例子,方便我们注意到要考虑的一些问题. 数组:[1, -2, 3, 5, -3, 2] 应该返回8,最大和的子数组为3,5 数组:[0, -2,

[经典面试题][淘宝]求首尾相连数组的最大子数组和

题目 给定一个由N个整数元素组成的数组arr,数组中有正数也有负数,这个数组不是一般的数组,其首尾是相连的.数组中一个或多个连续元素可以组成一个子数组,其中存在这样的子数组arr[i],-arr[n-1],arr[0],-,arr[j],现在请你这个ACM_Lover用一个最高效的方法帮忙找出所有连续子数组和的最大值(如果数组中的元素全部为负数,则最大和为0,即一个也没有选). 输入: 输入包含多个测试用例,每个测试用例共有两行,第一行是一个整数n(1<=n<= 100000),表示数组的长度

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

比如对于数组[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

最长公共子序列|最长公共子串|最长重复子串|最长不重复子串|最长回文子串|最长递增子序列|最大子数组和

参考:http://www.ahathinking.com/archives/124.html 最长公共子序列 1.动态规划解决过程 1)描述一个最长公共子序列 如果序列比较短,可以采用蛮力法枚举出X的所有子序列,然后检查是否是Y的子序列,并记录所发现的最长子序列.如果序列比较长,这种方法需要指数级时间,不切实际. LCS的最优子结构定理:设X={x1,x2,……,xm}和Y={y1,y2,……,yn}为两个序列,并设Z={z1.z2.……,zk}为X和Y的任意一个LCS,则: (1)如果xm=

用分治和递归的思想——寻找最大子数组

寻找最大子数组的问题可描述为 输入: 一个数组,一个低位,一个高位 输出: 数组中从低位到高位中,连续和最大是多少 首先能想到的最直接的办法是暴力解决,遍历所有可能的序列组合,如果有n个元素,则需遍历的子序列有,复杂度为n2,稍有些经验的就能马上意识到,有很多重复计算在里面,比如最长的子序列计算,包含了之前所有子序列的计算.接下来我们使用分治的思想求解这个最大子序列,前一篇博文提过,分治的思想是将大问题分解为同等类型的子问题,再将子问题求解,然后合并子问题得出原问题的解,其中用到了递归的思想,因

O(n)时间解决的面试题:乘积最大子数组

leetcode 152 ? ? 问题描述 ? ? 给定一个数组,求最大的连续子数组乘积最大 ? ? 分析问题 ? ? 跟求和最大子数组类似,我们也可以用动态规划来解这道题,解题之前我们需要考虑是否存在溢出,在不存在溢出的情况下我们需要记录之前乘积的绝对值,这里因为有正负性,负负得正,所以我们需要记录之前乘积的最大值和最小值两个值 ? ? 算法实现 ? ? int maxProduct(vector<int> &nums){ int n=nums.size(); if(n==0){ /