简单的递归问题
我正在迈出递归和动态编程的第一步,并且有一个关于形成子问题来建模递归的问题。
问题:
有多少种不同的方法 抛一枚公平的硬币 5 次,没有 连续三个或更多头?
如果有人可以提供一些带有大量注释的代码(Ruby 是首选,但不是必需的)来帮助我实现目标。 如果这很重要的话,我不是学生,这是对 Project Euler 问题的修改,使其对我来说非常简单去把握。 我只需要掌握编写递归公式的技巧。
如果您想将问题抽象为有多少种不同的方法可以抛一枚公平的硬币 Y 次,并且不会连续出现 Z 次或更多次正面,这也可能是有益的。 再次感谢,这个网站很棒。
I'm taking my first steps into recursion and dynamic programming and have a question about forming subproblems to model the recursion.
Problem:
How many different ways are there to
flip a fair coin 5 times and not have
three or more heads in a row?
If some could put up some heavily commented code (Ruby preferred but not essential) to help me get there. I am not a student if that matters, this is a modification of a Project Euler problem to make it very simple for me to grasp. I just need to get the hang of writing recursion formulas.
If you would like to abstract the problem into how many different ways are there to flip a fair coin Y times and not have Z or more heads in a row, that may be beneficial as well. Thanks again, this website rocks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以简单地为此创建一个公式:
抛硬币 5 次且连续出现 3 个正面的方法数等于抛 5 次硬币的组合数减去连续出现至少 3 个正面的组合数。 在这种情况下:
组合总数 = 2^5 = 32。 且 32 - 7 = 25。
如果我们连续抛硬币 N 次,且没有连续出现 Q 个正面,则总金额为 2^N,并且至少有Q 个头为 2^(N-Q+1)-1。 所以一般的答案是:
当然可以用递归来模拟总量:
You can simply create a formula for that:
The number of ways to flip a coin 5 times without having 3 heads in a row is equal to the number of combinations of 5 coin flips minus the combinations with at least three heads in a row. In this case:
The total number of combinations = 2^5 = 32. And 32 - 7 = 25.
If we flip a coin N times without Q heads in a row, the total amount is 2^N and the amount with at least Q heads is 2^(N-Q+1)-1. So the general answer is:
Of course you can use recursion to simulate the total amount:
这是我在 Ruby 中的解决方案
所有递归方法都从早期结束的情况开始。
这返回一个组合数组,其中唯一长度为零的组合是
[]
下一位(简化的)是...
所以..这说的是..我想要所有比所需的长度,每个都添加一个 :head...加上所有较短的组合,并添加一个尾部。
考虑递归的方法是..“假设我有一种方法来执行 n-1 情况..我必须添加什么才能使其覆盖 n 情况”。 对我来说,这感觉就像归纳证明。
该代码将生成给定长度的所有头和尾的组合。
我们不想要那些有 :h :h :h 的。 只有当我们有 :h :h 并且我们添加 :h 时才会发生这种情况。 所以...我在添加 :h 时添加了
if c[0..1] != [:h,:h]
,这样它将返回nil
当它要进行无效组合时,而不是数组。然后我必须
压缩
结果以忽略所有nil
结果Here's my solution in Ruby
All recursive methods start with an early out for the end case.
This returns an array of combinations, where the only combination of zero length is
[]
The next bit (simplified) is...
So.. this says.. I want all combinations that are one shorter than the desired length with a :head added to each of them... plus all the combinations that are one shorter with a tail added to them.
The way to think about recursion is.. "assuming I had a method to do the n-1 case.. what would I have to add to make it cover the n case". To me it feels like proof by induction.
This code would generate all combinations of heads and tails up to the given length.
We don't want ones that have :h :h :h. That can only happen where we have :h :h and we are adding a :h. So... I put an
if c[0..1] != [:h,:h]
on the adding of the :h so it will returnnil
instead of an array when it was about to make an invalid combination.I then had to
compact
the result to ignore all results that are justnil
这不是采取所有可能的 5 位序列并删除存在三个连续 1 位的情况(假设 1 = 头,0 = 尾)的问题吗?
Isn't this a matter of taking all possible 5 bit sequences and removing the cases where there are three sequential 1 bits (assuming 1 = heads, 0 = tails)?
这是在 Python 中执行此操作的一种方法:
Here's one way to do it in Python:
这可以分解为:
当第一次抛掷正面时,有多少种方法将一枚公平的硬币抛四次;当第一次抛掷是反面时,有多少种方法:
所以在Python中:
This breaks down to:
How many ways are there to flip a fair coin four times when the first flip was heads + when the first flip was tails:
So in python:
这是使用 Ruby
yield
语句的递归组合函数:您可以使用正则表达式连续解析出三个头:
最后,您将使用类似这样的内容得到答案:
所以这就是我要做的它 :)
Here's a recursive combination function using Ruby
yield
statements:And you could use regular expressions to parse out three heads in a row:
Finally, you would get the answer using something like this:
So that's how I would do it :)