ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

动态归划之换零钱

2021-12-30 02:05:51  阅读:165  来源: 互联网

标签:meno 换零钱 return 归划 coins amount num 动态 dp


# -*- encoding : utf-8 -*-
# @Author : 日落了
# @ Motto : 天不生python,IT 万古如长夜
# @project_name : DUOyi
# @Time : 2021/12/26
# @description : 凑零钱

# 双函数是为了将num待下去给dp函数 ,因为只是用一个函数的话需要将list写在外面 可读性差,问题来了,dp什么时候需要双参数 什么时候需要一个参数呢?
def func(num, coins: list):
    meno = dict()  # 因为有对应的值,最少的硬币现在的数量的价值

    # 这里的dp含义是dp[n]:当前数值为n的时候 ,所需要最小的硬币数
    def dp(num):
        # 备忘录 n 已经在字典里面的话 ,就不用重复地去计算dp[n]
        if num in meno:
            return meno[num]
        # 通过画出来的递归树可以看到sub问题里面存在着 硬币数为负值或者是0的情况。
        if num == 0:
            return 0
        if num < 0:
            return -1
        # 设置为0的话,min 比较会出错
        res = float('INF')
        for coin in coins:
            # 子问题的含义是 答案 = 前一个子答案加多一个硬币
            sub = dp(num - coin)
            if sub == -1:
                continue

            res = min(sub + 1, res)
        # 字典
        meno[num] = res
        return meno[num]

    return dp(num)


def coinChange(amount: int, coins: list) -> int:
    n = len(coins)
    dp = [[0 for _ in range(n + 1)] for i in range(amount + 1)]
    # 总数为0的时候
    # base
    if amount == 1:
        dp[1][1] = 1
        return 1
    if amount == 0:
        return 0
    for i in range(1, n):
        dp[0][i] = 0

        # dp[1][1] = 1
    for j in range(1, n):
        for i in range(1, amount):
            # 要不起

            if (i < coins[j - 1]):
                dp[i][j] = dp[i][j - 1]
                continue
            dp[i][j] = min(dp[i][j - 1], dp[i - coins[j - 1]][j] + 1)
    return dp[amount][n]


if __name__ == '__main__':
    print(func(11, [1, 2, 5]))
    print(coinChange(11, [1, 2, 5]))

 

# -*- encoding : utf-8 -*-
# @Author : 日落了
# @ Motto : 天不生python,IT 万古如长夜
# @project_name : DUOyi
# @Time : 2021/12/26
# @description : 凑零钱

# 双函数是为了将num待下去给dp函数 ,因为只是用一个函数的话需要将list写在外面 可读性差,问题来了,dp什么时候需要双参数 什么时候需要一个参数呢?
def func(num, coins: list):
meno = dict() # 因为有对应的值,最少的硬币现在的数量的价值

# 这里的dp含义是dp[n]:当前数值为n的时候 ,所需要最小的硬币数
def dp(num):
# 备忘录 n 已经在字典里面的话 ,就不用重复地去计算dp[n]
if num in meno:
return meno[num]
# 通过画出来的递归树可以看到sub问题里面存在着 硬币数为负值或者是0的情况。
if num == 0:
return 0
if num < 0:
return -1
# 设置为0的话,min 比较会出错
res = float('INF')
for coin in coins:
# 子问题的含义是 答案 = 前一个子答案加多一个硬币
sub = dp(num - coin)
if sub == -1:
continue

res = min(sub + 1, res)
# 字典
meno[num] = res
return meno[num]

return dp(num)


def coinChange(amount: int, coins: list) -> int:
n = len(coins)
dp = [[0 for _ in range(n + 1)] for i in range(amount + 1)]
# 总数为0的时候
# base
if amount == 1:
dp[1][1] = 1
return 1
if amount == 0:
return 0
for i in range(1, n):
dp[0][i] = 0

# dp[1][1] = 1
for j in range(1, n):
for i in range(1, amount):
# 要不起

if (i < coins[j - 1]):
dp[i][j] = dp[i][j - 1]
continue
dp[i][j] = min(dp[i][j - 1], dp[i - coins[j - 1]][j] + 1)
return dp[amount][n]


if __name__ == '__main__':
print(func(11, [1, 2, 5]))
print(coinChange(11, [1, 2, 5]))

标签:meno,换零钱,return,归划,coins,amount,num,动态,dp
来源: https://www.cnblogs.com/icxk/p/15747292.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有