您的位置:首页 > 其它

最大积连续子序列问题

2011-10-12 00:00 344 查看
对于最大积问题:

由于负数的存在,我们不能简简单单只存一个当前最大值,我们还需要存当前最小值。

我们令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]}

实际上,这个递推公式是重点。

/// <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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息