用lisp做最少金币
lisp吧
全部回复
仅看楼主
level 4
love_mely2 楼主
输入钱的总数cents,列表lst可以用的面额,如果省略输入就是(25 10 5 1) 。
程序输出为最少金币数。用动态规划做,代码如下:
(defun make-best-change(cents &optional (lst'(25 10 5 1)))
(if(< cents (car(last lst)))
0
(let((minw most-positive-fixnum))
(do((i lst(rest i)))
((null i)minw)
(unless(>(car i)cents)
(setf minw(min minw (1+ (make-best-change(- cents (car i))lst)))))))))
当cents值比较小是可以顺利找对,但是当cents大一点,比如67,程序就直接卡死了,
怀疑是递归效率太低的问题。
各位吧友有啥好建议?
2012年10月21日 20点10分 1
level 8
其实换一个算法比较好
                             ————酷容,你怎么看

2012年10月22日 00点10分 2
这个算法是贪心吧?有时候不行呀,比如钱币总数为30,可用硬币为(25,10,1),3个10分的硬币就可以了,但是这个程序找到的答案是6
2012年10月22日 02点10分
@love_mely2 好吧,其实我是看到原来的面额能避免这种情况才这么写的
2012年10月22日 04点10分
level 4
love_mely2 楼主
程序要求处理各种况,如果找不出来一个组合可以满足题目,那么就用最接近的
程序更正如下:
(defun make-best-change(cents &optional(lst'(25 10 5 1)))
(cond((null (cdr lst))(floor cents (car lst)))
((< cents (car(last lst)))0)
((< cents (car lst))(make-best-change cents (cdr lst)))
(t (let ((x (floor cents (car lst))))
(do((i x (1- i))
(minw most-positive-fixnum
(min minw (+ i (make-best-change(- cents (* i (car lst)))(cdr lst))))))
((< i 0)minw))))))
但是有一种情况还是不对,当恰好可以找开的时候,程序返回了一个找不开的最小组合。比如(MAKE-BEST-CHANGE 32 '(11 7)) 答案应该是 4 但是显示 3。
真心无力了,求教

2012年10月22日 02点10分 3
level 8
再写一个,这次应该没问题了
       ————Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:16.0) Gecko/20100101 Firefox/16.0
2012年10月22日 05点10分 4
[鲁拉]
2012年10月22日 07点10分
辛苦啦!但是如果要求钱数是凑不出来的,就返回最接近值的最小钱币数。这该怎么办呢?比如输入 [$1](MAKE-BEST-CHANGE 11 '(7 3)),就输出2。 题目要求是输出使用金币的序列,比如 (MAKE-BEST-CHANGE 11 '(7 3)) ,就输出(1 1)代表7使用1次,3使用1次。
2012年10月22日 19点10分
2012年10月22日 19点10分
@love_mely2 第一种情况把前面的1+去掉就可以了吧,第二种无非就是把加换成列表的连接,求和,道理一样的
2012年10月22日 23点10分
level 4
love_mely2 楼主
改成这样的版本可以正确计算出金币数了,但是我不会用列表输出各个金币各用了多少啊。
(defun make-best-change(cents &optional (lst '(25 10 5 1)))
(do((j cents (1- j))(k most-positive-fixnum (m2 j lst)))
((< k most-positive-fixnum)k)))
(defun m2(cents lst)
(if(null(cdr lst))
(multiple-value-bind(coins rest)(floor cents(car lst))
(if(zerop rest)coins
most-positive-fixnum))
(loop for i from 0 to(floor cents(car lst))minimize
(+ i(m2(- cents(* i (car lst)))(cdr lst))))))
2012年10月23日 14点10分 6
2012年10月23日 14点10分
level 8
有点忙,所以有点晚,不过已弄完
2012年10月24日 10点10分 7
十分感谢!我也写出了一个程序,呵呵~你是程序员吗?
2012年10月24日 20点10分
回复 love_mely2 :学生党一个
2012年10月25日 08点10分
1