算法基础——动态规划(3)背包 完全背包(每个物品可以重复选)

322. 零钱兑换
最开始考虑成选几个或不选的情况,这样写超时。只需要考虑选或不选这个数一次,选的话i(当前选择的数)不变,只是改变剩下需要凑的数值。

Solution1:递归+备忘录

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        target=amount
        @cache
        def dfs(target,i):
            if i<0:
                return 0 if target==0 else inf
            if target==0:
                return 0
            if target<coins[i]:
                return dfs(target,i-1)
            return min(dfs(target,i-1),dfs(target-coins[i],i)+1)
        ans=dfs(target,len(coins)-1)
        return ans if ans<inf else -1

Solution2:递推

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        #Solution 2
        d=[[inf]*(amount+1) for i in range(len(coins)+1)]
        d[0][0]=0
        for m in range(1,len(coins)+1):
            for n in range(0,amount+1):
                if n-coins[m-1]<0:
                    d[m][n]=d[m-1][n]
                else:
                    d[m][n]=min(d[m][n-coins[m-1]]+1,d[m-1][n])
        ans=d[len(coins)][amount] 
        return ans if ans<inf else -1

Solution3:空间优化
空间优化到一个数组时,可以注意一下不变的位置和变得位置,从会变的位置开始修改可以减少if,else判断语句。

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        #Solution 3
        d=[inf]*(amount+1)
        d[0]=0
        for x in coins:
            for n in range(x,amount+1):
                    d[n]=min(d[n],d[n-x]+1)
        return d[-1] if d[-1]<inf else -1

518. 零钱兑换 II
相对于上一题改动递推式为+即可。

class Solution:
    def change(self, amount: int, coins: List[int]) -> int:
        d=[1]+[0]*amount
        for x in coins:
            for m in range(x,amount+1):
                d[m]=d[m-x]+d[m]
        return d[-1]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值