C++ 最大字阵子段和,报错,谁帮我看看

思路:O(n)边读入边处理如果前面嘚子段和大于0,那么就用当前的加上前面的否则就是当前的,并随时更新最大字阵和就是

    有n个数(以下都视为整数)每個数有正有负,现在要在n个数中选取相邻的一段使其和最大字阵,输出最大字阵的和

    看到这个问题,它是属于带“最”字的问题其實就是一个求最优解的问题。对于这种问题的朴素算法就是枚举出每种可能然后在其中寻找一个最优的解,然后输出因为输出仅要求這个子段的和,因此不必再记录关于解的组成的信息

    朴素算法是用i和j表示序列i到j的子段,然后判断这个子段的和是否是最大字阵的是僦记录。然后用k求i到j之间的和因此是O(n^3)的算法。

    看了这个算法我们不禁会想,有没有能更快的算法呢毕竟O(n^3)的时间效率是很低的。答案肯定是有的我们可以令一个数组sum,sum[i]代表了序列从1到i的和如果要算i到j的和,只需将sum[j]减去sum[i-1]即可这无疑可以去掉最里层的循环,从而直接調用和的信息时间效率提高到O(n^2)。

    上面两种算法都是朴素算法枚举每个可能,从而找到最优的解然而还有没有更优的解呢?答案依旧昰肯定的

我们不妨从小规模数据分析,当序列只有一个元素的时候最大字阵的和只有一个个可能,就是选取本身;当序列有两个元素嘚时候只有三种可能,选取左边元素、选取右边元素、两个都选这三个可能中选取一个最大字阵的就是当前情况的最优解;对于多个え素的时候,最大字阵的和也有三个情况从左区间中产生、从右区间产生、左右区间各选取一段。因此不难看出这个算法是基于分治思想的,每次二分序列直到序列只有一个元素或者两个元素。当只有一个元素的时候就返回自身的值有两个的时候返回3个中最大字阵嘚,有多个元素的时候返回左、右、中间的最大字阵值因为是基于二分的思想,所以时间效率能达到O(nlgn)

有了O(nlgn)的递归算法,那还能找到O(n)线性时间的算法么——动态规划。我们令一个数组ff[i]表示前i个元素能组成的最大字阵和。如果f[i-1]大于零则不管a[i]的情况,f[i-1]都可以向正方向影響a[i]因此可以将a[i]加在f[i-1]上。如果f[i-1]小于零则不管a[i]再大,都会产生负影响因此我们还不如直接令f[i]=a[i]。因此状态转移方程就在这里我们只需在fΦ扫描一次,找到最大字阵的值就是最大字阵子段的和

    以上四个算法,从3个不同的思想解决了最大字阵子段和问题不管从时间效率还昰代码量来说,动态规划都是最优的仅需要一个辅助数组f来临时存取,因此时间复杂度空间复杂度都是线性的

最大字阵子段和裸题我傻了,看见l<r就加了个num终判判掉了,去了就A了很水的一个题,我想多了既然f[i]=a[i]-a[i+1],就已经保证l<r了做题少想些,少点套路多点真诚。

给出一段序列选出其中连续且非空的一段使得这段和最大字阵。

输入文件maxsum1.in的第一行是一个正整数N表示了序列的长度。

第2行包含N个绝对值不大于10000的整数A[i]描述了这段序列。

输入文件maxsum1.out仅包括1个整数为最大字阵的子段和是多少。子段的最小长度为1

我怎么记得这个题目贪心也可以做。

d[i]表示前i个数的最优值

我要回帖

更多关于 子问题 的文章

 

随机推荐