【动态规划~(上)】


子问题的重复计算:

代码如下:

```vbnet
# -*- coding = utf-8 -*-
# @Time : 2022/5/28 11:09
# @Author : lxw_pro
# @File : py-28.py
# @Software : PyCharm

# 子问题的重复计算:
import time
start = time.time()


def fib(n):
    if n == 1 or n == 2:
        return 1
    else:
        return fib(n-1)+fib(n-2)


print(fib(30))
end = time.time()
print("用递归的方法所运行的时间为", end-start)

动态规划【dp】思想————递推式

代码如下:

```vbnet
start2 = time.time()


def fib_no_rec(n):
    f = [0, 1, 1]
    if n > 2:
        for i in range(n-1):
            num = f[-1]+f[-2]
            f.append(num)
    return f[n]


print(fib_no_rec(100))
end2 = time.time()
print("用动态规划所运行的时间为", end2-start2)

测试时间小框架

代码如下:

```vbnet
def cal_time(func):
    def wra(*args, **kwargs):
        t1 = time.time()
        res = func(*args, **kwargs)
        t2 = time.time()
        print("%s running time:%s secs." % (func.__name__, t2-t1))
    return wra

钢条切割问题————递推式

代码如下:

```vbnet
p = [0, 1, 5, 8, 9, 10, 17, 17, 20, 21, 24, 26, 27, 27, 28, 30, 33, 36, 39, 42]


def cut_rec(p, n):
    if n == 0:
        return 0
    else:
        res = p[n]
        for i in range(1, n):
            res = max(res, cut_rec(p, i)+cut_rec(p, n-i))
        return res


@cal_time
def c1(p, n):
    return cut_rec(p, n)

自顶向下递归实现————最优子结构

代码如下:

```vbnet
def cut_rejh(p, n):
    if n == 0:
        return 0
    else:
        res = 0
        for i in range(1, n+1):
            res = max(res, p[i]+cut_rejh(p, n-i))
        return res


print(c1(p, 9))
print(cut_rec(p, 9))


@cal_time
def c2(p, n):
    return cut_rejh(p, n)


print(c2(p, 15))
print(cut_rejh(p, 15))

动态规划解法:

'''
递归算法由于重复求解相同子问题,效率极低
动态规划的思想:
每个子问题只求解一次,保存求解问题
之后需要此问题时,只需查找保存的结果

'''

自底向下实现–字典

代码如下:

def cut_dp(p, n):
    r = [0]
    for i in range(1, n+1):
        res = 0
        for j in range(1, i+1):
            res = max(res, r[i-j]+p[j])
        r.append(res)
    return r[n]


@cal_time
def c2(p, n):
    return cut_dp(p, n)


print(c2(p, 15))
print(cut_dp(p, 15))

重构解

代码如下:

def cut_extend(p, n):
    r = [0]
    s = [0]
    for i in range(1, n+1):
        res_r = 0   # 价格的最大值
        res_s = 0   # 价格最大值对应方案的左边不切割部分的长度
        for j in range(1, i+1):
            if p[j]+r[i-j] > res_r:
                res_r = p[j]+r[i-j]
                res_s = j
        r.append(res_r)
        s.append(res_s)
    return r[n], s


def cut_sol(p, n):
    r, s = cut_extend(p, n)
    t = []
    while n>0:
        t.append(s[n])
        n -= s[n]
    return t


# r, s = cut_extend(p, 10)
# print(s)
print(cut_sol(p, 10))

什么问题可以使用动态规划方法?

'''
最优子结构:
    原问题的最优解中涉及多少个子问题
    在确定最优解使用哪些子问题时,需要考虑多少种选择
    
重叠子问题

'''

上一章链接:二叉树的前序、中序、后序及层次遍历

每日一言:

一星陨落,黯淡不了星空灿烂;一花凋落,荒芜不了整个夏天。

持续更新中…

欢迎关注公众号【程序人生6】,一起探究学习哦!
程序人生6

猜你喜欢

转载自blog.csdn.net/m0_66318554/article/details/124994763