最大子段和:線性序列的最大子段和的三種解法

 

//線性序列的最大子段和的三種解法

1. 蠻力法

int MaxSubSum1(int* arr, int n, int& iPos, int& jPos)

{

        int sum = 0;

        // i和j是子串的起始位置。

        for (int i = 0; i < n; ++i)

            for (int j = i; j < n; ++j)

            {

                int thisSum = 0;

                // 計算當前子串的長度。

                for (int k = i; k <=j; ++k)

                    thisSum += arr[k];

                // 更新目前爲止最大子串的長度和最大子串的起始位置。

                if (thisSum > sum)

                {

                    sum = thisSum;

                    iPos = i;

                    jPos = j;

                }

            }

        return sum;

}

算法的改進:

int MaxSubSum2(int* arr, int n, int& iPos, int& jPos)

{

        int sum = 0;

        for (int i = 0; i < n; ++i)

        {

            int thisSum = 0;

            for (int j = i; j < n; ++j)

            {

                // 這樣thisSum就能重複利用已經加起來的值,而不是每次都從零開始。

                thisSum += arr[j];

                if (thisSum > sum)

                {

                    sum = thisSum;

                    iPos = i;

                    jPos = j;

                }

            }

        }

        return sum;

}

2. 分治法:

int MaxSubSum3(int* arr, int left, int right)

{

        int sum = 0;

        // Small(P)

        if (left == right)

            sum = arr[left] > 0 ? arr[left] : 0;

        // If P is not small, divide P into subproblems.

        else

        {

            // Find where to split the set.

            int center = (left + right ) / 2;

            // Solve the subproblems (1) and (2) recursively.

            int leftSum = MaxSubSum3(arr, left, center);

            int rightSum = MaxSubSum3(arr, center+1, right); 

 // Solve the subproblem (3)

            int s1 = 0, lefts = 0;

            for (int i = center; i >= left; --i)

            {

                lefts += arr[i];

                if (lefts > s1)

                    s1 = lefts;

            }

            int s2 = 0, rights = 0;

            for (int i = center + 1; i <= right; ++i)

            {

                rights += arr[i];

                if (rights > s2)

                    s2 = rights;

            }

            // Combine the solutions of the subproblems.

            sum = s1 + s2;

            if (sum < leftSum)

                sum = leftSum;

            if (sum < rightSum)

                sum = rightSum;

        }

        return sum;

}

3. 動態規劃法:

int MaxSubSum4(int* arr, int n, int& beg, int& end)

{

        int sum = 0, thisSum = 0, j = 0;

for (int i = 0; i < n; ++i)

        {

            // 根據動態規劃式決定取捨。

            if (thisSum >= 0)

                thisSum += arr[i];

            else

            {

                this
Sum = arr[i];

                j = i;

            }

            if (thisSum > sum)

            {

                sum = thisSum;

                end = i;

                beg = j;

            }

        }

        return sum;

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章