Python实现递归

本文探讨了递归与分治的联系及其在优化问题中的应用,以兑换最少硬币为例阐述贪心策略、递归策略和动态规划解法。通过动态规划方法解决找零问题,减少了重复计算,提高了效率。动态规划的核心是记录中间结果,确保从小规模问题的最优解推导出大规模问题的最优解。
摘要由CSDN通过智能技术生成

目录

递归与分治

联系

 应用

 优化问题

最优解问题——兑换最少个数硬币问题

贪心策略

递归策略 

动态规划解法 

总结


递归与分治

联系

递归三定律:

  1. 基本结束条件:解决最小规模问题;
  2. 缩小规模,向基本结束演进;
  3. 调用自身解决已缩小规模的相同问题:

即:

      问题解决依赖于若干缩小规模的问题,这些问题结果汇总得到原问题的解

 应用

排序、查找、遍历、求值

 优化问题

最优解问题——兑换最少个数硬币问题

贪心策略

  • 贪心策略

从最大面值的硬币开始,用尽可能多的数量

用最多数量的最大面值硬币来迅速减少找零面值

硬币的比值是由贪心策略制定的(Elbonia——杜撰国家中的21分硬币)

严格依赖于币值的体系

递归策略 

  •  递归策略

减小问题的规模——递归调用

 

def dpMakeChange(coinValueList,change,minCoins,coinsUsed):
   for cents in range(change+1):
      coinCount = cents
      newCoin = 1   #最小规模,直接返回
      for j in [c for c in coinValueList if c <= cents]:
            if minCoins[cents-j] + 1 < coinCount:
               coinCount = minCoins[cents-j]+1 # cent-j:减小规模(每次减去一种硬币面值)
               newCoin = j
      minCoins[cents] = coinCount
      coinsUsed[cents] = newCoin
   return minCoins[change]

def printCoins(coinsUsed,change):
   coin = change
   while coin > 0:
      thisCoin = coinsUsed[coin]
      print(thisCoin)
      coin = coin - thisCoin

def main():
    amnt = 63
    clist = [1,5,10,21,25]
    coinsUsed = [0]*(amnt+1)
    coinCount = [0]*(amnt+1)

    print("Making change for",amnt,"requires")
    print(dpMakeChange(clist,amnt,coinCount,coinsUsed),"coins")
    print("They are:")
    printCoins(coinsUsed,amnt)
    print("The used list is as follows:")
    print(coinsUsed)

main()

但是,重复计算次数太多,因此递归算法改进的关键就是消除重复计算

将之前的最优解记录,在需要用的时候直接调用

 

动态规划解法 

  • 动态规划解法

之前中间结果记录称之为记忆化/函数值缓存(memorization)

 

 

从小往大,计算11=1+10(每次依靠之前已知的最优解)

能用动态规划解决问题的必要条件:问题的最优解包含了更小规模子问题的最优解

 

总结

  1. 递归式解决某些具有自相似性的复杂问题的有效技术;
  2. 递归算法“三定律“;
  3. 本质:不断减小问题的规模,调用自身,指导可以具备基本结束条件的解决为止;
  4. 递归通常能和问题的表达自然契合;
  5. 递归可能导致巨量的计算;
  6. 函数值缓存可以通过附加存储空间记录中间计算结果来有效减少重复计算;
  7. 如果一个问题最优解包括最小相同问题的最优解,则可以用动态规划解决(从小到大)
  8. 递归和动态规划二者之间可以相互转换
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值