最大子段和:线性序列的最大子段和的三种解法

 

//线性序列的最大子段和的三种解法

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;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值