1、三重循環暴力求解
例程:
int MaxSubsequenceSum(const int A[], int N)
{
int ThisSum, MaxSum, i, j, k;
MaxSum = 0;
for(int i = 0; i < N; i++)
for(int j = i; j < N; j++)
{
ThisSum = 0;
for(k = i; k <= j; k++)
ThisSum += A[k];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
}
return MaxSum;
}
分析復雜度:
復雜度為
\[\sum^{n}_{i = 1}(\sum_{j = i}^n(j - i)) \]
而
\[\sum_{j = i}^n(j - i) = \frac{(n - i)(n - i + 1)}{2} = \frac{(n - i)^2}{2} + \frac{n- i}{2} \]
\(\Rightarrow\)
\[\sum_{i = 1}^n(\frac{(n - i)^2}{2} + \frac{n - i}{2}) = O(n^3) \]
2、兩重循環
上面的三重循環可以撤除一個,以此來獲取平方級別的復雜度
例程:
int MaxSubsequenceSum(const int A[], int N)
{
int ThisSum, MaxSum, i, j;
MaxSum = 0;
for(int i = 0; i < N; i++)
{
ThisSum = 0;
for(int j = i; j < N; j++)
{
ThisSum += A[j];
if(ThisSum > MaxSum)
MaxSum = ThisSum;
}
}
return MaxSum;
}
易知,復雜度為
\[\sum_{i = 1}^{n}(n - i) = O(n^2) \]
3、分治
例程:
static int MaxSubSum(const int A[], int Left, int Right)
{
int MaxLeftSum, MaxRightSum; // 左右部分各自的最大子序列和
int MaxLeftBorderSum, MaxRightBorderSum; // 包括邊界的左右最大子序列和的最大值(從中間開始往左右延伸),這兩個數最后要相加到一起,然后和上面的兩個數比較,它們的和的本質其實是跨越中間邊界的最大子序列和
int LeftBorderSum, RightBorderSum; // 存儲臨時值
int center, i;
if(Left == Right)
if(A[Left] > 0)
return A[Left];
else
return 0;
Center = (Left + Right) / 2;
MaxLeftSum = MaxSubSum(A, Left, Center);
MaxRightSum = MaxSubSum(A, Center + 1, Right);
MaxLeftBorderSum = 0;
LeftBorderSum = 0;
for(i = Center; i >= Left; i—)
{
LeftBorderSum += A[i];
if(LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}
MaxRightBorderSum = 0;
RightBorderSum = 0;
for(i = Center + 1; i <= Right; i ++)
{
RightBorderSum += A[i];
if(RightBorderSum > MaxRightBorerSum)
MaxRightBorderSum = RightBorderSum;
}
return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
}
int MaxSubSequenceSum(const int A[], int N)
{
return MaxSubSum(A, 0, N - 1);
}
\[T(n) = 2T(\frac{n}{2}) + O(n) \]
\(\Rightarrow\)
\[T(n) = O(nlogn) \]