动态规划算法

动态规划算法

一.爬楼梯问题

from IPython.display import Image
Image(filename="./data/8_01.png",width=800,height=960)

output_2_0.png

def upstairs(n):
    if n<1:
        print(0)
    if n==1:
        print(1)
    if n==2:
        print(2)
    
    a=1
    b=2

    temp=0
    for i in range(3,n+1):
        temp=a+b
        a=b
        b=temp
        
    print(temp)
upstairs(10)
89

完整代码

a=1
b=2

temp=0

def upstairs(n):
    if n<1:
        print(0)
    if n==1:
        print(1)
    if n==2:
        print(2)
    
    for i in range(3,n+1):
        temp=a+b
        a=b
        b=temp
        
    print(temp)

二.矿工挖矿

Image(filename="./data/8_02.png",width=800,height=960)

output_8_0.png

def goldMining(n,w,g,p):
    results=[]
    preResults=[]
    
    for i in range(0,w):
        results.append(0)
        
        if i<p[0]:
            preResults.append(0)
        else:
            preResults.append(g[0])
            
    for i in range(0,n):
        for j in range(0,w):
            if j<p[i]:
                results[j]=preResults[j]
            else:
                results[j]=max(preResults[j],preResults[j-p[i]]+g[i])
                
        preResults=results
        
    return results
n=5
w=10

g=[400,500,200,300,350]
p=[5,5,3,4,3]

goldMining(n,w,g,p)
[0, 0, 0, 350, 350, 500, 700, 700, 850, 1050]

二.背包问题

Image(filename="./data/8_03.png",width=800,height=960)

output_12_0.png

Image(filename="./data/8_04.png",width=800,height=960)

output_13_0.png

def bag(n,c,w,v):
    res=[[-1 for j in range(c+1)] for i in range(n+1)]
    
    for j in range(c+1):
        res[0][j]=0
        
    for i in range(1,n+1):
        for j in range(1,c+1):
            res[i][j]=res[i-1][j]
            
            if j>=w[i-1] and res[i][j]<res[i-1][j-w[i-1]]+v[i-1]:
                res[i][j]=res[i-1][j-w[i-1]]+v[i-1]
                
    return res


def show(n,c,w,res):
    print("最大价值为:",res[n][c])
    
    x=[False for i in range(n)]
    
    j=c
    
    for i in range(1,n+1):
        if res[i][j]>res[i-1][j]:
            x[i-1]=True
            j-=w[i-1]
            
    print("选择的物品为:")
    
    for i in range(n):
        if x[i]:
            print("第%d个"%i,end=" ")
            
    print(" ")
    
if __name__=="__main__":
    n=5
    c=10
    w=[2,2,6,5,4]
    v=[6,3,5,4,6]
    
    res=bag(n,c,w,v)
    show(n,c,w,res)
最大价值为: 15
选择的物品为:
第0个 第1个 第4个

三.最长递归子序列

Image(filename="./data/8_05.png",width=800,height=960)

output_16_0.png

Image(filename="./data/8_06.png",width=800,height=960)

output_17_0.png

def getdp1(arr):
    n=len(arr)
    dp=[0]*n
    
    for i in range(n):
        dp[i]=1
        
        for j in range(i):
            if arr[i]>arr[j]:
                dp[i]=max(dp[i],dp[j]+1)
                
    return dp

def generateLIS(arr,dp):
    n=max(dp)
    index=dp.index(n)
    lis=[0]*n
    n-=1
    lis[n]=arr[index]
    
    for i in range(index,0-1,-1):
        if arr[i]<arr[index] and dp[i]==dp[index]-1:
            n-=1
            lis[n]=arr[i]
            index=i
    return lis
arr=[6,7,8,9,10,1,2,3,4,5,6]
dp=getdp1(arr)
generateLIS(arr,dp)
[1, 2, 3, 4, 5, 6]
def getdp2(arr):
    n=len(arr)
    dp,ends=[0]*n,[0]*n
    ends[0],dp[0]=arr[0],1
    right,l,r,m=0,0,0,0
    
    for i in range(1,n):
        l=0
        r=right
        
        while l<=r:
            m=int((l+r)/2)
            
            if arr[i]>ends[m]:
                l=m+1
            else:
                r=m-1
                
        right=max(right,1)
        ends[l]=arr[i]
        dp[i]=l+1
    return dp
getdp2(arr)
[1, 2, 3, 3, 3, 1, 2, 3, 3, 3, 3]
原文地址:https://www.cnblogs.com/LQ6H/p/12940556.html