一、动态规划简单实例

【题目】

        当我们给定一个简单序列[1、5、2、4、3],现在要求输出该序列中,最大子序列的长度,子序列要求从小到大,元素下标可以跳跃,例如子序列[1、2、3]。

【实现方式(暴力实现)】

1、先定义一个函数L(nums,i),

(1)传入参数为全部子序列和某一个元素的下标,

(2)作用是找到以该元素为首元素,最长子序列的长度,并返回这个长度

2、再定义一个函数length_of_LIS(nums),

(1)传入参数为全部序列,

(2)作用是循环调用L(nums,i)函数,依次将每个元素的下标传入,得到L(nums,i)函数的返回值,再取返回值的最大值,作为最大子序列的长度,

3、在if __name__=="__main__":中调用length_of_LIS(nums)函数,传入被查找序列,得到其最大子序列的长度,

【实现代码(暴力实现)】

"""
最长子序列
"""


def L(nums, i):
    """
    传入参数为全部序列和某一个元素的下标,
    该函数的作用是,找到以该下标元素为首元素的最长子序列
    it will return the max number from your list
    :return:Null
    """
    if i == len(nums) - 1:
        return 1
    # 初始化子系列的长度为1
    max_len = 1
    for j in range(i + 1, len(nums)):
        if nums[i] < nums[j]:
            max_len = max(max_len, L(nums, j) + 1)
    return max_len


def length_of_LIS(nums):
    """
    传入参数为全部序列,和每一个元素的下标
    调用L(nums,i)函数,得到以(每个元素为首元素的)最长子序列的长度,取其最大值,返回
    :param nums:
    :return:
    """
    return max(L(nums, i) for i in range(len(nums)))


if __name__ == '__main__':
    nums = [1, 5, 2, 4, 3]
    print(length_of_LIS(nums))

【时间time】

 可以看到,暴力算法的时间大概在0.66秒左右,

一、动态规划简单实例_第1张图片

【实现方式(动态规划)】

1、初始化一个字典things,

(1)key:存储下标

(2)value:存储以key为下标的元素作为首元素,所能组成的最长子序列的长度

2、在调用L(nums,i)时,先查找things字典的key是否有i,如果有,查看以该元素为首元素,所形成的最长子序列的长度,并将其返回,这样会节省很大运行时间。

【实现代码(dp算法)】

"""
最长子序列
"""
import time

# 定义things字典,key存储序列的元素,value存储该key元素,所能组成的最长的子序列的长度
things = {}


def L(nums, i):
    """
    传入参数为全部序列和某一个元素的下标,
    该函数的作用是,找到以该下标元素为首元素的最长子序列
    it will return the max number from your list
    :return:Null
    """
    # 查询下标为i的元素,以其为首元素所组成的最长子序列的长度
    if i in things:
        return things[i]
    if i == len(nums) - 1:
        return 1
    # 初始化子系列的长度为1
    max_len = 1
    for j in range(i + 1, len(nums)):
        if nums[i] < nums[j]:
            max_len = max(max_len, L(nums, j) + 1)
    return max_len


def length_of_LIS(nums):
    """
    传入参数为全部序列,和每一个元素的下标
    调用L(nums,i)函数,得到以(每个元素为首元素的)最长子序列的长度,取其最大值,返回
    :param nums:
    :return:
    """
    return max(L(nums, i) for i in range(len(nums)))


if __name__ == '__main__':
    start_time = time.time()
    nums = [1, 5, 2, 4, 3]
    print(length_of_LIS(nums))
    end_time = time.time()
    print(f"运行时间为{end_time - start_time}")

【时间time】

在使用了dp算法之后,时间大致在0.35秒左右

一、动态规划简单实例_第2张图片

你可能感兴趣的:(python算法,动态规划,python,算法)