动态规划经典题型

动态规划题

二进制数中1的个数

//0到num数中每个二进制表示中1的个数
def countBits(self, num):
        dp = [0]*(num+1)
        for i in range(0, num+1):
            dp[i] = (i & 1) + dp[i>>1]//位运算
        return dp 

扩展问题:

  • 给定两个正整数A,B,快速找出二进制表示中不同位数的个数?//AB异或,再求该数的1的个数
  • 判断一个数是否时2的幂//n&(n-1)==0;
  • v&=(v-1) ;cnt++;求1 的个数

硬币兑换方法数

def countMethod(arr,num):
    arr.sort()
    dp = [0]*(num+1)
    dp[0] =1
    for i in range(len(arr)):
        for j in range(arr[i],num+1):
            dp[j] = (dp[j]+dp[j-arr[i]])%1000000007
            //每个循环新增一类硬币,方法数新增(当前值减去硬币值后的方法数)
    return dp[-1]
arr = [1,5,10,25]
print(countMethod(arr,20))

硬币兑换最少硬币数

def Mincoin(arr,num):
    arr.sort()
    dp = [0]*(num+1)
    newcoins = {}//记录每次新增的硬币,用于回溯硬币组合
    for i in range(1,num+1):
        coin=i
        newcoin=0//新增硬币类型,也做是否能拼凑的标记
        for j in [c for c in arr if c<=i]:
            if dp[i-j]+1<coin and dp[i-j]!=-1:
                coin = dp[i-j]+1
                newcoin=j
        if newcoin!=0://可组合
            dp[i]=coin
        else://不能组合
            dp[i]=-1
        newcoins[i]=newcoin
    return dp[-1],newcoins
arr = [2,3]
num = 11
res,newcoins = Mincoin(arr,num)
coin = num
if newcoins[num]!=0:
    while coin>0:
        thisCoin = newcoins[coin]
        print(thisCoin)
        coin = coin-thisCoin
print(res)

0-1背包

def back01():
    C = 10  # 背包总体积
    num = 5 # 个数
    v   =   [4, 3, 5, 2, 5] # 体积
    price = [9, 6, 1, 4, 1]  # 价格
    dp=[0 for i in range(C+1)] # 
    for i in range(num): # 
        for j in range(C,v[i]-1,-1): # 逆序,保证每种类型只有一个
            dp[j]=max(dp[j],dp[j-v[i]]+price[i])
    print("一维递归计算结果:",dp[C])
back01()

完全背包

def backFull():
    C = 10  # 背包总体积
    num = 5 # 个数
    v   =   [4, 3, 5, 2, 5] # 体积
    price = [9, 6, 1, 4, 1]  # 价格
    dp=[0 for i in range(C+1)] # 
    for i in range(num): # 
        for j in range(v[i],C+1): # 新增物品,比较价格
            dp[j]=max(dp[j],dp[j-v[i]]+price[i])
    print("一维递归计算结果:",dp[C])
backFull()

高楼扔鸡蛋问题

import sys
def eggDrop(k,n):
    visited={}
    def dp(k,n):
        if k==1:
            return n
        if n==0:
            return 0
        if (k,n) in visited:
            return visited[(k,n)]
        res = sys.maxsize
        for i in range(1,n+1):
            res = min(res,max(dp(k,n-i),dp(k-1,i-1))+1)
        visited[(k,n)] = res
        return res
    return dp(k,n)

res = eggDrop(2,100)
print(res)

posted @ 2020-09-23 18:57  yourText  阅读(116)  评论(0编辑  收藏  举报