• 动态规划DP算法


    python实现钢条切割问题与最长工公共序列问题

    #动态规划算法DP代码:

    #递归法计算斐波那契数列f(n)=f(n-1)+f(n-2)
    #递归算法-执行效率比较低,相同的问题算了好多遍—子问题的重新计算
    def fibnacci(n):
    if n==1 or n==2:
    return 1
    else:
    return fibnacci(n-1)+fibnacci(n-2)
    print(fibnacci(5))

    #非递归算法-执行效率高
    #动态规划DP思想=最优子结构,递推式子+重复子问题存储
    def fibnacci1(n):
    f=[0,1,1]
    if n>2:
    for i in range(n-2):
    num=f[-1]+f[-2]
    f.append(num)
    return f[n]
    print(fibnacci1(100))

    #钢条切割问题的递归算法
    from cal_time import *
    p=[0,1,5,8,9,10,17,17,20,21,23,24,26,27,27,28,30,33,36,39,40]
    P=[0,1,5,8,9,10,17,17,20,24,30]

    #使用递归的思想进行计算算法1
    #自定向顶上,时间复杂度度为O(2**n)
    def cut_rod_recurision(p,n):
    if n==0:
    return 0
    else:
    res=p[n]
    for i in range(1,n):
    res=max(res,cut_rod_recurision(p,i)+cut_rod_recurision(p,n-i))
    return res
    #使用递归的思想计算算法2
    def cut_rod_recurision2(p,n):
    if n==0:
    return 0
    else:
    res=0
    for i in range(1,n+1):
    res=max(res,p[i]+cut_rod_recurision2(p,n-i))
    return res

    #使用动态规划DP的思想实现钢条切割问题
    #自底向上思想
    @cal_time
    def cut_rod_DP(p,n):
    r=[0]
    for i in range(1,n+1):
    res=0
    for j in range(1,i+1):
    res=max(res,p[j]+r[i-j])
    r.append(res)
    return r[n]

    #输出解决方案的切割长度函数
    def cut_rod_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_rod_solution(p,n):
    r,s=cut_rod_extend(p,n)
    ans=[]
    while n>0:
    ans.append(s[n])
    n-=s[n]
    return ans
    #递归算法输出函数运行时间需要进行函数的重新定义
    @cal_time
    def c1(p,n):
    return cut_rod_recurision(p,n)
    @cal_time
    def c2(p,n):
    return cut_rod_recurision2(p,n)

    print(c1(p,15))
    print(c2(p,20))
    print(cut_rod_solution(p,20))
    print(cut_rod_DP(p,20))
    #使用动态规划DP的思想实现最长公共子序列的问题
    #最长公共子序列问题
    #使用动态规划算法来进行解决
    def lcs_length(x,y):
    m=len(x)
    n=len(y)
    c=[[0 for _ in range(n+1)] for _ in range(m+1)] #创建一个m行n列的二维列表
    for i in range(1,m+1):
    for j in range(1,n+1):
    if x[i-1]==y[j-1]: #i,j的字符匹配的时候,来自于左上方的数值+1
    c[i][j]=c[i-1][j-1]+1
    else:
    c[i][j]=max(c[i-1][j],c[i][j-1])
    return c[m][n]

    def lcs(x,y):
    m = len(x)
    n = len(y)
    c = [[0 for _ in range(n + 1)] for _ in range(m + 1)]
    b = [[0 for _ in range(n + 1)] for _ in range(m + 1)] #1为左上方,2上方,3左方
    for i in range(1,m+1):
    for j in range(1,n+1):
    if x[i-1]==y[j-1]: #i,j的字符匹配的时候,来自于左上方的数值+1
    c[i][j]=c[i-1][j-1]+1
    b[i][j]=1 #记录来自的方向
    elif c[i-1][j]>c[i][j-1]: #来自于上方
    c[i][j]=max(c[i-1][j],c[i][j-1])
    b[i][j]=2
    else:
    c[i][j] = max(c[i - 1][j], c[i][j - 1])
    b[i][j]=3
    return c[m][n],b
    #回溯法找回输出的最优方案
    def lcs_trackback(x,y):
    c,b=lcs(x,y)
    i=len(x)
    j=len(y)
    res=[]
    while i>0 and j>0:
    if b[i][j]==1: #来自左上方
    res.append(x[i-1])
    i=i-1
    j=j-1
    elif b[i][j]==2: #来自上方
    i-=1
    else: #来自左方
    j-=1
    return "".join(reversed(res))

    c,b=lcs("ABCBDAB","BDCABA")
    print(c)
    print(lcs_trackback("ABCBDAB","BDCABA"))
    
    




  • 相关阅读:
    rpcbind禁用不了,111端口无法释放?
    python3 pexpect 自动交互修改linux系统密码
    pip将包安装到指定位置
    使用openssl对文件进行加密解密
    james-2.3.2.1发邮件慢,不能多线程同时发
    java指令执行一个class文件并指定依赖包的路径
    ltib for imx280 tips
    使用net-snmp的snmptranslate命令验证MIB文件
    嵌入式linux去掉开机进度条,更换背景,换企鹅logo
    使用cppcheck对C代码进行静态检查
  • 原文地址:https://www.cnblogs.com/Yanjy-OnlyOne/p/12457415.html
Copyright © 2020-2023  润新知