如何计算代表n美分的方式数量 [英] How to calculate the number of ways to represent n cents

查看:85
本文介绍了如何计算代表n美分的方式数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究以下算法,想知道我的实现是否正确:

I'm working on the following algorithm and wanted to know if my implementation is correct:


给定无限个季度,角钱,镍币和便士,
编写代码以计算代表n美分的方式数量。

Given an infinite number of quarters, dimes, nickels and pennies, write code to calculate the number of ways of representing n cents

def count_ways(n)
  return 0 if n < 0 
  return 1 if n == 0 

  count_ways(n-25) + count_ways(n-5) + count_ways(n-10) + count_ways(n-1)
end


推荐答案

我们可以看到您的代码是否正确容易。让我们尝试改变一角钱。有四种方式:1个角钱,2个镍币,1个镍币和5个便士,以及10个便士,但 count_ways(10)#=> 9

We can see if your code is correct quite easily. let's try making change for a dime. There are four ways: 1 dime, 2 nickels, 1 nickel and 5 pennies, and 10 pennies, yet count_ways(10) #=> 9.

您可以使用递归操作如下。

You can do it as follows, using recursion.

代码

def count_ways(cents, coins)
  if coins.size == 1
    return (cents % coins.first) == 0 ? [cents/coins.first] : nil
  end 
  coin, *remaining_coins = coins
  (0..cents/coin).each_with_object([]) { |n, arr|
    count_ways(cents-n*coin, remaining_coins).each { |a| arr << [n, *a] } }
end 

示例

coins = [25, 10, 5, 1]

count_ways(32, coins)
  #=> [[0, 0, 0, 32], [0, 0, 1, 27], [0, 0, 2, 22], [0, 0, 3, 17], [0, 0, 4, 12],
  #    [0, 0, 5,  7], [0, 0, 6,  2], [0, 1, 0, 22], [0, 1, 1, 17], [0, 1, 2, 12],
  #    [0, 1, 3,  7], [0, 1, 4,  2], [0, 2, 0, 12], [0, 2, 1,  7], [0, 2, 2,  2],
  #    [0, 3, 0,  2], [1, 0, 0,  7], [1, 0, 1,  2]] 

count_ways(100, coins)
  #=> [[0, 0, 0, 100], [0, 0, 1, 95], [0, 0, 2, 90], [0, 0, 3, 85], [0, 0, 4, 80],
  #    [0, 0, 5,  75], [0, 0, 6, 70], [0, 0, 7, 65], [0, 0, 8, 60], [0, 0, 9, 55],
  #    ...
  #    [3, 1, 2,   5], [3, 1, 3,  0], [3, 2, 0,  5], [3, 2, 1,  0], [4, 0, 0,  0]] 
count_ways(100, coins).size
  #=> 242 

说明

显示递归工作方式的最佳方法是使用puts语句对代码加盐,然后针对一个简单示例运行它。

The best way to show how the recursion works is to salt the code with puts statements and then run it against a simple example.

INDENT = 8
@indentation = 0

def indent
 @indentation += INDENT
end

def undent
 @indentation = [@indentation-INDENT, 0].max
end

def ind
  ' '*@indentation
end

def count_ways(cents, coins)
  puts "#{ind}** entering count_ways with cents=#{cents}, coins=#{coins}"
  if coins.size == 1
    puts "#{ind}<< returning [cents]=#{[cents]} as coins.size == 1" 
    undent
  end  
  return [cents] if coins.size == 1
  coin, *remaining_coins = coins
  puts "#{ind}coin=#{coin}. remaining_coins=#{remaining_coins}"
  puts "#{ind}0..cents/coin=#{0..cents/coin}"
  arr = (0..cents/coin).each_with_object([]) do |n, arr|
    puts "#{ind}  n=#{n}, arr=#{arr}"
    puts "#{ind}  >> calling count_ways(#{cents}-#{n}*#{coin}, remaining_coins)"
    indent
    aa = count_ways(cents-n*coin, remaining_coins)
    puts "#{ind}  aa=#{aa}"
    aa.each do |a|
      arr << [n, *a]
      puts "#{ind}    arr << [#{n}, *#{a}], arr=#{arr}"
    end
    puts "#{ind}  after all coins, arr=#{arr}"
  end
  puts "#{ind}<< returning arr=#{arr}"
  undent
  arr
end

现在让我们运行 count_ways(12 ,硬币),它应以四种方式返回 12 美分的更改方式: [[0,0,0, 12],[0、0、1、7],[0、0、2、2],[0、1、0、2]]

Now let's run count_ways(12, coins) which should return the four ways of making change for 12 cents: [[0, 0, 0, 12], [0, 0, 1, 7], [0, 0, 2, 2], [0, 1, 0, 2]].

count_ways(12, coins)
** entering count_ways with cents=12, coins=[25, 10, 5, 1]
coin=25. remaining_coins=[10, 5, 1]
0..cents/coin=0..0
  n=0, arr=[]
  >> calling count_ways(12-0*25, remaining_coins)
        ** entering count_ways with cents=12, coins=[10, 5, 1]
        coin=10. remaining_coins=[5, 1]
        0..cents/coin=0..1
          n=0, arr=[]
          >> calling count_ways(12-0*10, remaining_coins)
                ** entering count_ways with cents=12, coins=[5, 1]
                coin=5. remaining_coins=[1]
                0..cents/coin=0..2
                  n=0, arr=[]
                  >> calling count_ways(12-0*5, remaining_coins)
                        ** entering count_ways with cents=12, coins=[1]
                        << returning [cents]=[12] as coins.size == 1

                  aa=[12]
                    arr << [0, *12], arr=[[0, 12]]
                  after all coins, arr=[[0, 12]]
                  n=1, arr=[[0, 12]]
                  >> calling count_ways(12-1*5, remaining_coins)
                        ** entering count_ways with cents=7, coins=[1]
                        << returning [cents]=[7] as coins.size == 1
                  aa=[7]
                    arr << [1, *7], arr=[[0, 12], [1, 7]]
                  after all coins, arr=[[0, 12], [1, 7]]
                  n=2, arr=[[0, 12], [1, 7]]
                  >> calling count_ways(12-2*5, remaining_coins)
                        ** entering count_ways with cents=2, coins=[1]
                        << returning [cents]=[2] as coins.size == 1

                  aa=[2]
                    arr << [2, *2], arr=[[0, 12], [1, 7], [2, 2]]
                  after all coins, arr=[[0, 12], [1, 7], [2, 2]]
                << returning arr=[[0, 12], [1, 7], [2, 2]]
          aa=[[0, 12], [1, 7], [2, 2]]
            arr << [0, *[0, 12]], arr=[[0, 0, 12]]
            arr << [0, *[1, 7]], arr=[[0, 0, 12], [0, 1, 7]]
            arr << [0, *[2, 2]], arr=[[0, 0, 12], [0, 1, 7], [0, 2, 2]]
          after all coins, arr=[[0, 0, 12], [0, 1, 7], [0, 2, 2]]
          n=1, arr=[[0, 0, 12], [0, 1, 7], [0, 2, 2]]
          >> calling count_ways(12-1*10, remaining_coins)
                ** entering count_ways with cents=2, coins=[5, 1]
                coin=5. remaining_coins=[1]
                0..cents/coin=0..0
                  n=0, arr=[]
                  >> calling count_ways(2-0*5, remaining_coins)
                        ** entering count_ways with cents=2, coins=[1]
                        << returning [cents]=[2] as coins.size == 1

                  aa=[2]
                    arr << [0, *2], arr=[[0, 2]]
                  after all coins, arr=[[0, 2]]
                << returning arr=[[0, 2]]
          aa=[[0, 2]]
            arr << [1, *[0, 2]], arr=[[0, 0, 12], [0, 1, 7], [0, 2, 2], [1, 0, 2]]
          after all coins, arr=[[0, 0, 12], [0, 1, 7], [0, 2, 2], [1, 0, 2]]
        << returning arr=[[0, 0, 12], [0, 1, 7], [0, 2, 2], [1, 0, 2]]
  aa=[[0, 0, 12], [0, 1, 7], [0, 2, 2], [1, 0, 2]]
    arr << [0, *[0, 0, 12]], arr=[[0, 0, 0, 12]]
    arr << [0, *[0, 1, 7]], arr=[[0, 0, 0, 12], [0, 0, 1, 7]]
    arr << [0, *[0, 2, 2]], arr=[[0, 0, 0, 12], [0, 0, 1, 7], [0, 0, 2, 2]]
    arr << [0, *[1, 0, 2]], arr=[[0, 0, 0, 12], [0, 0, 1, 7], [0, 0, 2, 2], [0, 1, 0, 2]]
  after all coins, arr=[[0, 0, 0, 12], [0, 0, 1, 7], [0, 0, 2, 2], [0, 1, 0, 2]]
<< returning arr=[[0, 0, 0, 12], [0, 0, 1, 7], [0, 0, 2, 2], [0, 1, 0, 2]]
 => [[0, 0, 0, 12], [0, 0, 1, 7], [0, 0, 2, 2], [0, 1, 0, 2]] 

这篇关于如何计算代表n美分的方式数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆