动态规划_硬币问题

假设有 1 元, 3 元, 5 元的硬币若干(无限) , 现在需要凑出 11 元,问如何组合才能使硬币的数量最少?

d(i) = d(j) + 1, j < i。通俗地讲,如果我们需要凑出 i 元,就在凑出 j 的结果上再加上某一个硬币就行了。

那这里我们加上的是哪个硬币呢。嗯,其实很简单,把每个硬币试一下就行了:

假设最后加上的是 1 元硬币,那 dp(i) = dp(i - 1) + 1。

假设最后加上的是 3 元硬币,那 dp(i)  = dp(i - 3) + 1。

假设最后加上的是 5 元硬币,那 dp(i) =  dp(i - 5) + 1。

 因此,分别计算出 dp(i - 1) + 1,dp(i - 3) + 1,dp(i - 5) + 1 的值,取其中的最小值,即为最优解 d(i),状态转移方程:

 dp[i] = min{dp[i - coins[j]] + 1},   其中 i >= coins[j], 0 <= j < coins.length 

 

def dynamic2(coins,amount):

    f=[amount+1 for i in range(amount+1)]
    f[0]=0
    for i in range(1,amount+1):
        for coin in coins:
            if coin<=i:
                f[i]=min(f[i],f[i-coin]+1)
    if f[i]==amount+1:
        return -1
    else:
        print(f)
        print(f[amount])


dynamic2(coins=[1,2,5],amount=11)
#[0, 1, 1, 2, 2, 1, 2, 2, 3, 3, 2, 3]

 

#三种银币,2元,5元,7元,每种硬币足够多,买一本书27元,如何用最小的硬币正好付清
def f(coins,money):#用最少硬币拼出money
    #初始化和边界
    f=[]
    for i in range(money+1):
        if i==0:
            f.append(0)
        else:
            f.append(float("inf"))
        
    #转移矩阵
    for i in range(0,money+1):
        for coin in coins:
            if(i>=coin) and f[i-coin]!=float("inf"):
                f[i]=min(f[i-coin]+1,f[i])
    if f[i]==float("inf"):
        return -1
    return f[moeny]
res=f([1,2,5],11)
print(res)

 

posted on 2020-09-27 18:27  happygril3  阅读(285)  评论(0)    收藏  举报

导航