动态规划求解最大连续子序列和

动态规划方法处理的准则:最优子结构、子问题重叠、边界 和 子问题独立

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# 求最大连续子序列和
"""
【题目】
 给定k个整数的序列{N1,N2,...,Nk },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },
 其中 1 <= i <= j <= k。最大连续子序列是所有连续子序中元素和最大的一个,
 例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{11,-4,13},最大连续子序列和即为20。

【注】:为方便起见,如果所有整数均为负数,则最大子序列和为0。
"""

def cal_mcs(ss):
    """
    穷举暴力破解求最大连续子序列  (时间复杂度O(n^3))
    :param ss:
    :return:
    """
    i = 0
    j = 0
    n = len(ss)-1
    cur_sum =0
    max_sum = 0

    for i in range(n):
        for j in range(i, n):
            cur_sum = 0
            for k in range(i, j):
                cur_sum += ss[k]
            if cur_sum > max_sum:
                max_sum = cur_sum
    return max_sum

def cal_mcs_2(ss):
    """
    # 动态规划算法:求最大连续子序列      时间复杂度(O(n))
        1) 令状态 k[j] 为最大连续子序列最后一个元素。令dk[j]表示最大连续子序列和
        2)这个最大连续子序列和为从 dk[i] ~ dk[j]
    # 分两种情况:
        1)最大和就是k[j]。它之前的序列和都小於k[j]
        2)最大和是dk[j-1]+k[j]。
    # 于是得到状态转移方程:
        dk[j] = max{dk[j-1]+k[j], k[j]}      边界为 dk[0] = j[0]

    # 动态规划算法计算特点(步骤):
        从后往前算,每步计算结果都记录进表。
        计算结束后,再遍历记录表。
    :param ss:
    :return:
    """

    dp = [ 0 for i in ss]
    dp[0] = 0
    for i in range(0, len(ss)):
        dp[i] = max( ss[i], dp[i-1] + ss[i] )
    curr_sum = dp[0]
    for sum in dp:
        if sum > curr_sum:
            curr_sum = sum
    print(dp)
    return curr_sum

ss = [ -2, 11, -4, 13, -5, -2]
# ss = [ -4, 11, -2, 13, -7, -3, 12 ]
print(cal_mcs_2(ss))

动态规划算法输出结果:

[-2, 11, 7, 20, 15, 13]
20

你可能感兴趣的:(算法,大数据)