Python递归

特殊的方法-循环:

#无法解决某些情况,例如存在21元的零钱
def fun(n):
    count = 0
    while n > 25:
        n = n - 25
        count = count + 1 
    while n > 10:
        n = n - 10
        count = count + 1 
    while n > 5:
        n = n - 10
        count = count + 1 
    while n > 0:
        n = n - 1
        count = count + 1  
    return count


print(fun(63))

特殊的方法 - 递归:

def fun(n):  # 分好类
    if n <= 0:
        return 0
    elif n >= 25:
        return 1 + fun(n-25)
    elif n >= 10:
        return 1 + fun(n-10)
    elif n >= 5:
        return 1 + fun(n-5)
    elif n >= 1:
        return 1 + fun(n-1)


print(fun(25))

递归 + 记忆:

import time
                                                              
def recMD(valueList, change, Knowlist):
    minNum = change
    if change in valueList:  # 可以作为结束条件
        Knowlist[change] = 1
        return 1
    elif Knowlist[change] > 0:  # 回忆
        return Knowlist[change]
    else:
        for i in [c for c in valueList if c <= change]:  # 常用
            num = 1 + recMD(valueList, change - i, Knowlist)
            if num < minNum:
                minNum = num
        Knowlist[change] = minNum
    return minNum  # 最后记得要返回
print(time.process_time())  # time.clock()被抛弃
print(recMD([1, 5, 10, 25], 77, [0]*79))  # 创建全为0的表
print(time.process_time())

递归 + 记忆 + 输出过程:

import time
from pythonds.basic.stack import Stack 


def dp(valueList, change, minNum, coinUsed):  # minNum初始化为0,之后需要利用到这些数据
    for cents in range(1, change+1):  # 从小到大递推
        coinCount = cents  # 初始化一个无害的最小值
        newCoin = 1
        for j in [c for c in valueList if c <= cents]:  # 常用技巧
            if 1 + minNum[cents-j] < coinCount:
                coinCount = 1 + minNum[cents - j]
                newCoin = j
        minNum[cents] = coinCount
        coinUsed[cents] = newCoin # 每一个change的最优解都是由两部分组成,这里是记录其中一部分
    return minNum[change]


def printSelection(change, coinused):
    coin = change
    s = Stack()
    while coin > 0:
        thisCoin = coinused[coin]
        s.push(thisCoin)
        coin = coin - thisCoin
    
    while not s.isEmpty():
        print(s.pop())


valList = [1, 5, 10, 25]
amnt = 63
minN = [0]*64
coinUsed = [0]*64
print(dp(valList, amnt, minN, coinUsed))  # 创建表的方式get
print(coinUsed[1:])  # 打印全部
printSelection(amnt, coinUsed)  # 打印组成部分

备注:

动态规划解法的必要条件:问题的最有解包含了更小规模的最优解,即每一步都要依靠前面某步的最优解
Talk is cheap. Show me the code. 将算法思路转化成具体代码需要不断实践,积累经验

原文地址:https://www.cnblogs.com/SKEZhi/p/13361464.html