递归与动态规划
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了递归与动态规划相关的知识,希望对你有一定的参考价值。
参考技术A 递归很简单,但是需要的时间和空间非常大。递归的时间复杂度:解决一个子问题的时间 * 子问题的个数。
而子问题的个数可以先画递归判定树,树的节点个数也就是子问题的个数,一般是2^n。
是指数级,往往增长的很快,很容易超时。
递归可以画树,当然是自顶向下进行求解。
动态规划相比于递归更加高效。
动态规划与递归不同的是,动态规划是自底向上求解,并且保存每一个子结果。
这样就可以很大程度地对递归判定树进行剪枝,极大地减少了时空的消耗。
动态规划某种程度上可以看做是有备忘录的递归算法。
动态规划的核心思想就是 拆分子问题,记住过往,减少重复计算。
参考资料: 看一遍就理解:动态规划详解 - 云+社区 - 腾讯云
递归 动态规划
递归与动态规划
1 # python 2 # -*- coding: utf-8 -*- 3 """ 4 __title__ = ‘‘ 5 __author__ = ‘wlc‘ 6 __mtime__ = ‘2017/10/14‘ 7 """ 8 import turtle 9 10 """ 11 递归三定律 12 递归算法必须有基本情况 13 递归算法必须改变其状态向基本情况靠近 14 递归算法必须以递归方式调用自身 15 """ 16 17 18 def sumList(list): 19 """ 20 program:递归求列表和 21 :param list: list 22 :return: sum 23 """ 24 if len(list) == 1: 25 return list[0] 26 else: 27 return list[0] + sumList(list[1:]) 28 29 30 def sysConversion(n, base): 31 """ 32 program:递归进制转换 33 :param n:十进制 34 :param base:转换的进制 35 :return: 目的进制 36 """ 37 str = "0123456789ABCDEF" 38 if n < base: 39 return str[n] 40 else: 41 return sysConversion(n // base, base) + str[n % base] 42 43 44 import turtle 45 46 47 def tree(branchLen, t): 48 """ 49 #program:递归建树 50 :param branchLen: 51 :param t: 52 :return: 53 """ 54 if branchLen > 5: 55 t.forward(branchLen) 56 t.right(20) 57 tree(branchLen - 15, t) 58 t.left(40) 59 tree(branchLen - 15, t) 60 t.right(20) 61 t.backward(branchLen) 62 63 64 def main(): 65 t = turtle.Turtle() 66 myWin = turtle.Screen() 67 t.left(90) 68 t.up() 69 t.backward(100) 70 t.down() 71 t.color("green") 72 tree(75, t) 73 myWin.exitonclick() 74 75 76 def changeMoney(coinList, change): 77 """ 78 program:找零钱问题(低效版本) 79 在递归过程中计算所有出现的结果进行比较但是里面存在 太多的相同步骤 80 26元(20 10 5 1) 81 (1 25(XXXXX)),(5 21)(10(重复计算) 16((1 15)(5 11)(10(重复计算) 6))(20 6) 82 因此要加入一个列表用来保存 83 84 :param coinList: 85 :param change: 86 :return: 87 """ 88 minNum = change 89 # 最小的基本情况 90 if change in coinList: 91 return 1 92 else: 93 # 筛选出比change大的硬币值 94 for x in [y for y in coinList if y <= change]: 95 numCoin = 1 + changeMoney(coinList, change - x) 96 if numCoin < minNum: 97 minNum = numCoin 98 return minNum 99 100 101 def changeMoneyUpgrade(coinList, change, memoryList): 102 """ 103 104 :param coinList: 货币表 105 :param change: 需要找的零钱 106 :param memoryList: 递归记录表(可以称之为缓存或者记忆化) 107 :return: 108 """ 109 minNum = change 110 # 最小的基本情况 111 if change in coinList: 112 memoryList[change] = 1 113 return 1 114 elif memoryList[change] > 0: 115 return memoryList[change] 116 else: 117 # 筛选出比change大的硬币值 118 for x in [y for y in coinList if y <= change]: 119 numCoin = 1 + changeMoneyUpgrade(coinList, change - x, memoryList) 120 if numCoin < minNum: 121 minNum = numCoin 122 memoryList[change] = minNum 123 return minNum 124 125 126 def dynamicProgramingChangeMoney(memoryList, moneyList, change): 127 """ 128 动态规划解决找零钱问题 129 :param memoryList: 记录所有小于change的最小找零数 130 :param moneyList:人民币1,2,5,10 20,50,100 131 :param change:需要找的零钱 132 change:1 2 3 4 5 6 7 8 9 10 11 133 moneyList:1 2 3 4 1 2 3 4 5 1 2 134 :return:moneyList 135 """ 136 for i in range(change + 1): 137 minNum = i 138 for j in [x for x in moneyList if x <= i]: 139 if memoryList[i - j] + 1 < minNum: 140 minNum = memoryList[i - j] + 1 141 memoryList[i] = minNum 142 return memoryList 143 144 145 def dynamicProgramingChangeMoneyTrace(memoryList, moneyUsedList, moneyList, change): 146 """ 147 动态规划解决找零钱问题 跟踪每一个找回的零钱的币种 148 :param memoryList: 记录所有小于change的最小找零数 149 :param moneyList:人民币1,2,5,10 20,50,100 150 :param change:需要找的零钱 151 :param moneyUsedList:需要找的第一个零钱的位置 用来跟踪位置 依次追踪到所有的位置 152 change:1 2 3 4 5 6 7 8 9 10 11 153 memoryList:1 2 3 4 1 2 3 4 5 1 2 154 moneyUsedList: 155 :return:moneyList moneyUsedList 156 """ 157 for i in range(change + 1): 158 minNum = i 159 newMoney = 1 160 for j in [x for x in moneyList if x <= i]: 161 if memoryList[i - j] + 1 < minNum: 162 minNum = memoryList[i - j] + 1 163 newMoney = j 164 memoryList[i] = minNum 165 moneyUsedList[i] = newMoney 166 return memoryList, moneyUsedList 167 168 169 def printChangeMoney(moneyUsedList, memoryList): 170 """ 171 用来打印找零钱的具体零钱列表 172 :param moneyUsedList: 173 :param memoryList: 174 :return: 175 """ 176 money = len(memoryList) - 1 177 while money > 0: 178 printValue = moneyUsedList[money] 179 print(printValue) 180 money = money - printValue 181 182 183 if __name__ == ‘__main__‘: 184 # sum = sumList([1, 2, 3, 4]) 185 # print(sum) 186 # print(sysConversion(18, 10)) 187 # # main() 188 # a = [0] * 64 189 # print(len(a)) 190 print(changeMoneyUpgrade([1, 5, 10,21, 25], 63, [0] * 64)) 191 print(dynamicProgramingChangeMoney([0] * 64, [1, 5, 10,21, 25], 63)) 192 memoryList, moneyUsedList = dynamicProgramingChangeMoneyTrace([0] * 64, [0] * 64, [1, 5, 10,21, 25], 63) 193 print(str(memoryList)+ ‘\n‘, str(moneyUsedList)) 194 printChangeMoney(moneyUsedList, memoryList)
以上是关于递归与动态规划的主要内容,如果未能解决你的问题,请参考以下文章