实例:换零钱方式统计

问题描述:共有50,25,10,5,1美分五种面值的钱币,现在要计算的是共有多少种换法.

解题思路会有一点点难想,主要思想是

1美元换成五种零钱 =(包含半美元的所有换法)+(不包含半美元的换法)

包含半美元的换法要求保证至少有一张半美元,余下的(1美元-半美元)继续用五种面值兑换。不包含半美元的换法也就是对1美元进行剩余四种面值兑换.根据上面的思路进行数学表达式的推理:

设f(a,n)为对数量为a的钱进行n种面值的兑换法的总数,则有:

f(a,n)=f(a-value(n),n) + f(a,n-1)

递归必须要有停止条件,在这里的递归停止条件是:

a=0 return 1 (a=0说明分配完了,得到一种分配方法)

a<0 or n=0 return 0 (a<0或者n=0说明未分配成功)

以下是python实现:

 V = [ 1, 5, 10 , 25, 50]

def f(a , n):
    if a == 0:
        return 1
    if (a < 0 or n == 0):
        return 0
    else:
        return f(a,n-1)+f(a-V[n-1],n) 

书中的Lisp实现

(define (count-change amount) (cc amount 5))

(define (cc amount kinds-of-coins)
(cond ((= amount 0) 1)
((or (< amount 0) (= kinds-of-coins 0)) 0)
(else (+ (cc amount
(- kinds-of-coins 1)) (cc (- amount
(first-denomination kinds-of-coins))
kinds-of-coins)))))


(define (first-denomination kinds-of-coins)
(cond ((= kinds-of-coins 1) 1)
((= kinds-of-coins 2) 5)
((= kinds-of-coins 3) 10)
((= kinds-of-coins 4) 25)
((= kinds-of-coins 5) 50)))

Exercise 1.11: A function f is defined by the rule that

\[f(n)=\left\{\begin{array}{l} n \text { if } n<3 \\ f(n-1)+2 f(n-2)+3 f(n-3) \text { if } n \geq 3 \end{array}\right.\]

Write a procedure that computes f by means of a recursive process.Write a procedure that computes f by means of an iterative process.

recursive process:

(define (f n)
  (cond ((< n 3) n)
        (else (+ (f (- n 1)) (* (f (- n 2)) 2) (* (f (- n 3)) 3)))))

iterative process: