lintcode练习 - 279. 凑 N 分钱的方案数

版权声明:原创部分都是自己总结的,如果转载请指明出处。觉得有帮助的老铁,请双击666! https://blog.csdn.net/qq_36387683/article/details/81948210

279. 凑 N 分钱的方案数

给你无限多个的 25 分,10 分,5 分和 1 分的硬币。问如果要凑出 n 分钱有多少种不同的方式?

样例

给出 n = 11

11 = 1 + 1 + 1... + 1
   = 1 + 1 + 1 + 1 + 1 + 1 + 5
   = 1 + 5 + 5
   = 1 + 10

返回 4

class Solution:
    """
    @param n: An integer
    @return: An integer
    """
    
    '''
    #暴力递归  TLE
    def waysNCents(self, n):
        # write your code here
        arr = [1, 5, 10, 25]
        if n < 0:
            return 0
        
        return self.process1(arr, 0, n)
    
    
    def process1(self, arr, index, n):
        res = 0
        if index == len(arr):
            res = 1 if n == 0 else 0
        else:
            i = 0
            while arr[index] * i <= n:
                res += self.process1(arr, index+1, n - arr[index] * i)
                i += 1
        
        return res
    '''
    
    '''
    #记忆化搜索 TLE
    def waysNCents(self, n):
        # write your code here
        arr = [1, 5, 10, 25]
        if n < 0:
            return 0
        
        me = [[0] * (n+1) for i in range(5)]
        
        return self.process2(arr, 0, n, me)
    
    def process2(self, arr, index, n, me):
        res = 0
        if index == len(arr):
            res = 1 if n==0 else 0
        else:
            mapValue = 0
            i = 0
            while arr[index] * i <= n:
                mapValue = me[index+1][n-arr[index]*i] 
                if mapValue != 0:
                    res += 0 if mapValue == -1 else mapValue
                else:
                    res += self.process2(arr, index+1, n-arr[index]*i , me)
                
                i += 1
        
        me[index][n] = -1 if res == 0 else res
        return res
    '''
    
    '''
    #动态规划  TLE
    def waysNCents(self, n):
        # write your code here
        arr = [1, 5, 10, 25]
        if n < 0:
            return 0
        
        dp = [[0] * (n+1) for _ in range(len(arr))]
        
        #组成钱数为0的方法只有一种
        for i in range(len(arr)):
            dp[i][0] = 1
        
        #矩阵第一行,表示第一种面值,能够组成钱数的方法
        k = 1
        while  arr[0] * k <= n:
            dp[0][arr[0]*k] = 1
            k += 1
        
        num = 0
        for i in range(1, len(arr)):
            for j in range(1, n+1):
                num = 0
                
                #用k张arr[i]货币,剩下的钱用比他面值小的钱arr[0..i-1]组成,方法数为dp[i][j] = dp[i-1][j-arr[i]*k]
                k = 0
                while j - arr[i]*k >= 0:
                    num += dp[i-1][j-arr[i]*k]
                    k += 1
                
                dp[i][j] = num
        
        return dp[-1][n]
    '''
    
    '''
    #动态规划 O(n*aim)
    #dp[i][j] = dp[i-1][j-arr[i]*k],第一种情况的方法数为dp[i-1][j];从2到第K种情况的累加值其实就是dp[i-1][j-arr[i]]的值
    def waysNCents(self, n):
        # write your code here
        arr = [1, 5, 10, 25]
        if n < 0:
            return 0
        
        dp = [[0] * (n+1) for _ in range(len(arr))]
        
        #组成钱数为0的方法只有一种
        for i in range(len(arr)):
            dp[i][0] = 1
        
        #矩阵第一行,表示第一种面值,能够组成钱数的方法
        k = 1
        while  arr[0] * k <= n:
            dp[0][arr[0]*k] = 1
            k += 1
        
        num = 0
        for i in range(1, len(arr)):
            for j in range(1, n+1):
                #可以完全用前一种面值组成
                dp[i][j] = dp[i-1][j]
                #加上用自己的面值组成
                dp[i][j] += dp[i][j - arr[i]] if j-arr[i] >= 0 else 0
        
        return dp[-1][n]
    '''
    
    #动态规划 空间压缩 O(n*aim) S(aim)
    def waysNCents(self, n):
        # write your code here
        arr = [1, 5, 10, 25]
        if n < 0:
            return 0
        
        dp = [0] * (n+1)
        
        #面值arr[0]可以组成的钱数
        k=0
        while arr[0] * k <= n:
            dp[arr[0] * k] = 1
            k += 1
        
        for i in range(1, len(arr)):
            for j in range(1, n+1):
                dp[j] += dp[j-arr[i]] if j-arr[i] >= 0 else 0 
        
        return dp[-1]

猜你喜欢

转载自blog.csdn.net/qq_36387683/article/details/81948210