学习一下bbschat的解法.
我做的原始的版本
@all = 0
@coins = [200,100,50,20,10,5,2,1]
@result = 200
def addto(v, i)
#p @all.to_s+" "+v.to_s+" "+i.to_s
return if @coins.size <= i
if (@coins.size-1==i)
@all += 1
return
end
0.upto(@result/@coins[i]) do |j|
@all += 1 if @result == j*@coins[i]+v
break if @result <= j*@coins[i]+v
addto(j*@coins[i]+v, i+1)
end
end
start = Time.new
addto(0,0)
p @all
p Time.new - start时间是0.531, bbs是0.21. 于是想学习一下.
-------------------------------------------------------
1. @all 可以用返回来代替, return if @coins.size <= i 删掉.
第二版
@coins = [200,100,50,20,10,5,2,1]
@result = 200
def addto(v, i)
return 1 if (@coins.size-1==i)
all = 0
0.upto(@result/@coins[i]) do |j|
all += 1 if @result == j*@coins[i]+v
return all if @result <= j*@coins[i]+v
all += addto(j*@coins[i]+v, i+1)
end
end
start = Time.new
p addto(0,0)
p Time.new - start快了一点, 0.484. 但还是慢, 问题在哪儿?
bbschat的循环里没有判断, 这可能是关键. 但为什么不需要呢?
我注意到程序的循环条件是从0到value除币值, 这儿的value和我的@result是不一样的.是指剩下来还有多少钱没找.
所以我的循环必须要判钱是否找多了, bbschat的不用判.
----------------------------------------------------
去掉这些判断, 第三版
@coins = [200,100,50,20,10,5,2,1]
Result = 200
LastI = @coins.size - 1
def addto(v, i)
return 1 if (LastI==i)
all = 0
0.upto((Result-v)/@coins[i]) {|j| all += addto(j*@coins[i]+v, i+1)}
all
end
start = Time.new
p addto(0,0)
p Time.new - start这个好象差不多了. 0.234