动态规划 零钱问题 python

零钱问题:


暴力递归:

     递推关系:对arr[index]的使用的次数情况进行枚举,for(int i=0,arr[index]*i<=aim,i++),对于每一个i都对应一个枚举的情况,在该枚举情况下可以重新调整参数,此时可以使用的零钱数组是arr中index+1开始及之后的数组部分,新的目标值是aim=(aim-arr[index]*i),于是调用递归方法dp(arr,index+1,aim-arr[index]*i)即可返回当前枚举条件下的方案数目,对每一种情况下的方案数目进行累加即可得到总的方案数目。

     边界条件:可以发现其实边界条件,就是思考什么时候满足拼凑,什么时候不能够实现拼凑,显然,当递归到aim=0时表名可以拼凑出目标值,当 aim小于0的时候表名该方法不能得到目标值,递归的边界条件就是当index==length时判断aim==0是否成立,若成立+1,否则+0

class Exchange:
    def countWays(self, penny, n, aim):
        if len(penny)<=0 or aim<0:
            return 0
        else:
            return(self.pl(penny,0,aim))
    def pl(self,arr,index,aim):
        res= 0
        if index == len(arr):
            if aim == 0:
                res = 1
            else:
                res = 0
        else:
            i = 0
            while arr[index]*i<=aim:    
                res = res+self.pl(arr,index+1,aim-arr[index]*i)
                i = i+1
        return res
//测试代码

penny = [1,2,4]
n = 3
aim = 3
a = Exchange()
print(a.countWays(penny,n,aim))

记忆查找

# -*- coding: utf-8 -*-


class Exchange:
    def countWays(self, penny, n, aim):
            # write code here
        if len(penny)<=0 or aim<0:
            return 0
        else:
            dic = {}
            for index in range(n+1):
                for a in range(aim+1):
                    dic[(index,a)] = 0   
                #print('dic_ori=',dic)
            return(self.pl(penny,0,aim,dic))
    def pl(self,arr,index,aim,dic):
        res= 0
        if index == len(arr):
            if aim == 0:
                res = 1
            else:
                res = 0
        else:
            i = 0
            value = 0
            while arr[index]*i<=aim:
                value = dic[(index+1,aim-arr[index]*i)]
                if value!=0:  
                    res = res+value
                else:
                    res = res+self.pl(arr,index+1,aim-arr[index]*i,dic)
                i = i+1
            if res!=0:
                dic[(index,aim)] = res
            #print('dic=',dic)
        return res
penny = [1,2,4]
n = 3
aim = 3
a = Exchange()
print(a.countWays(penny,n,aim))

动态规划

 

class Exchange:
    def countWays(self, penny, n, aim):
        # write code here
        dic = {}
        for i in range(n):
            for j in range(aim+1):
                dic[(i,j)] = 0
        i=0
        while penny[0]*i<=aim:
            dic[(0,penny[0]*i)] = 1
            i = i+1
        for a in range(n):
            dic[(a,0)] = 1
        print('dic=',dic)    
        for i in range(1,n):
            for j in range(1,aim+1):
                if j>=penny[i]:
                    dic[(i,j)] = dic[(i-1,j)]+dic[(i,j-penny[i])]
                else:
                    dic[(i,j)] = dic[(i-1,j)]
        print(dic)
        return dic[(n-1,aim)]
penny = [1,2,4]
n = 3
aim = 3
a = Exchange()
print(a.countWays(penny,n,aim))

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值