经典 - 最大和/最大积连续子序列问题
2011-05-26 00:06
316 查看
原文:
http://fayaa.com/tiku/view/56/
对于一个包含了正负整数的数组,求其“最大和”连续子序列 以及 “最大积”连续子序列
比如:
3 -4 8 -5 2 6 -7
最大和子序列是:8 -5 2 6,和为11
最大积子序列是:3 -4 8 -5 2 6,积自己算:)
对于最大和问题:
我们令F(n)表示[0,n]区间内以d
为结尾的最大和,d为原序列,那么有:
F(n + 1) = Max{d[n + 1],F(n) + d[n + 1]} = d[n + 1] + Max{0, F(n)}
对于最大积问题:
由于负数的存在,我们不能简简单单只存一个当前最大值,我们还需要存当前最小值。
我们令F(n)表示[0,n]区间内以d
为结尾的最大积,令G(n)表示[0,n]区间内以d
为结尾的最小积,d为原序列,那么有:
F(n + 1) = Max{F(n) * d[n + 1], d[n + 1], G(n) * d[n + 1]}
G(n + 1) = Min{F(n) * d[n + 1], d[n + 1], G(n) * d[n + 1]}
代码如下:
最大子段和结果为:
11
最优序列为:
8 -5 2 6
最大子段积结果为:
5760
最优序列为:
3 -4 8 -5 2 6
http://fayaa.com/tiku/view/56/
对于一个包含了正负整数的数组,求其“最大和”连续子序列 以及 “最大积”连续子序列
比如:
3 -4 8 -5 2 6 -7
最大和子序列是:8 -5 2 6,和为11
最大积子序列是:3 -4 8 -5 2 6,积自己算:)
对于最大和问题:
我们令F(n)表示[0,n]区间内以d
为结尾的最大和,d为原序列,那么有:
F(n + 1) = Max{d[n + 1],F(n) + d[n + 1]} = d[n + 1] + Max{0, F(n)}
对于最大积问题:
由于负数的存在,我们不能简简单单只存一个当前最大值,我们还需要存当前最小值。
我们令F(n)表示[0,n]区间内以d
为结尾的最大积,令G(n)表示[0,n]区间内以d
为结尾的最小积,d为原序列,那么有:
F(n + 1) = Max{F(n) * d[n + 1], d[n + 1], G(n) * d[n + 1]}
G(n + 1) = Min{F(n) * d[n + 1], d[n + 1], G(n) * d[n + 1]}
代码如下:
using System; public class FayaaView56 { /// <summary> /// 求解最大子段和,返回结果以及最优解的始末下标 /// </summary> /// <param name="seq">输入序列</param> /// <param name="beginIndex">返回最优解的起始下标</param> /// <param name="endIndex">返回最优解的结束下标</param> /// <returns>最大子段和</returns> public static int MaxSubSum(int[] seq, out int beginIndex, out int endIndex) { if (seq == null || seq.Length == 0) throw new ArgumentNullException("输入序列不能为空"); int bestResult = seq[0]; beginIndex = endIndex = 0; int curSum = seq[0], curBeginIndex = 0; for (int i = 1; i < seq.Length; i++) { if (curSum > 0) { curSum += seq[i]; } else { curSum = seq[i]; curBeginIndex = i; } if (curSum > bestResult) { bestResult = curSum; beginIndex = curBeginIndex; endIndex = i; } } return bestResult; } /// <summary> /// 求解最大子段积,返回结果以及最优解的始末下标 /// </summary> /// <param name="seq">输入序列</param> /// <param name="beginIndex">返回最优解的起始下标</param> /// <param name="endIndex">返回最优解的结束下标</param> /// <returns>最大子段积</returns> public static long MaxSubMul(int[] seq, out int beginIndex, out int endIndex) { if (seq == null || seq.Length == 0) throw new ArgumentNullException("输入序列不能为空"); long maxMul = seq[0]; beginIndex = endIndex = 0; long curMaxMul = seq[0], curMinMul = seq[0]; int curMinBeginIndex = 0, curMaxBeginIndex = 0; for (int i = 1; i < seq.Length; i++) { long a = curMaxMul * seq[i], b = curMinMul * seq[i]; long max, min; int tmpMaxBeginIndex, tmpMinBeginIndex; if(a > b) { max = a; min = b; tmpMaxBeginIndex = curMaxBeginIndex; tmpMinBeginIndex = curMinBeginIndex; } else { max = b; min = a; tmpMaxBeginIndex = curMinBeginIndex; tmpMinBeginIndex = curMaxBeginIndex; } if (seq[i] > max) { curMaxBeginIndex = i; curMaxMul = seq[i]; } else { curMaxBeginIndex = tmpMaxBeginIndex; curMaxMul = max; } if (seq[i] < min) { curMinBeginIndex = i; curMinMul = seq[i]; } else { curMinBeginIndex = tmpMinBeginIndex; curMinMul = min; } if (curMaxMul > maxMul) { maxMul = curMaxMul; beginIndex = curMaxBeginIndex; endIndex = i; } } return maxMul; } public static void Main() { int[] seq = { 3, -4, 8, -5, 2, 6, -7}; int beginIndex, endIndex; Console.WriteLine("最大子段和结果为:"); Console.WriteLine(MaxSubSum (seq, out beginIndex, out endIndex)); Console.WriteLine("最优序列为:"); for (int i = beginIndex; i <= endIndex; i++) { Console.Write(seq[i] + " "); } Console.WriteLine(); Console.WriteLine("最大子段积结果为:"); Console.WriteLine(MaxSubMul(seq, out beginIndex, out endIndex)); Console.WriteLine("最优序列为:"); for (int i = beginIndex; i <= endIndex; i++) { Console.Write(seq[i] + " "); } Console.WriteLine(); } }
最大子段和结果为:
11
最优序列为:
8 -5 2 6
最大子段积结果为:
5760
最优序列为:
3 -4 8 -5 2 6
相关文章推荐
- 经典的递归问题(全排列、从n个球中取出m个球、最大公共子序列 )
- 连续子序列最大和问题的四种经典解答
- 最大积连续子序列问题
- 【编程学习】最大子序列和问题-经典-online线性算法
- HDU-1003-Max Sum(dp经典问题-最大连续子序列和)
- 经典问题--最大子序列和的个人简单整理
- dp经典问题最大子序列和问题
- 经典最大子序列和问题
- 最大连续子序列和的问题
- HDU1003 最大子序列和问题
- 最大子序列和问题
- 【算法与数据结构】最大子序列和问题
- 最大子序列求和问题
- 最大子序列和问题
- 分治法和动态规划法解最大子序列问题 C++
- 最大子序列和问题四种解(O)
- HDU 1231 最大连续子序列 &&HDU 1003Max Sum (区间dp问题)
- 算法学习之最大子序列问题
- 求序列的最大子序列和的问题
- java 动态规划最大公共子序列问题