我开始练习动态编程,只是无法解决这个问题:
问题:
一个孩子正在向上爬n级楼梯,可以一次跳1步,2步或3步。实施一种方法来计算孩子可以上楼梯的可能性。
破解编码访谈书的解决方案是这样的:
”“如果我们考虑到第n步的所有路径,我们可以将它们建立在前三个步骤的路径的基础上。我们可以通过以下任何一种方法到达第n个停靠点:
因此要找到解决方案,只需将这些路径的数量加在一起即可!
那是让我迷失的地方!为什么这样的答案不是:先添加这些路径的数量,再添加3?由于如果您要执行步骤n-1或n-2或n-3,那么有3种方法可以执行第n步?我了解,如果您写下前4个基数案例的答案(假设n = 0返回1),您会看到类似斐波那契的模式。但是您可能也看不到它,所以很难。
然后they提出了以下代码:
public static int countWaysDP(int n, int[] map) {
if (n < 0)
return 0;
else if (n == 0)
return 1;
else if (map[n] > -1)
return map[n];
else {
map[n] = countWaysDP(n - 1, map) + countWaysDP(n - 2, map) + countWaysDP(n - 3, map);
return map[n]; }
}
第二个问题。当n == 0时如何返回1。即使我接受这一事实,如果在n == 1时返回0,我仍然找不到解决方法。
希望这很有道理。
谢谢
答案 0 :(得分:0)
这是我如何把头缠在这个地方-
从书中-
在最后一跳,直到第 n 步,孩子可能已经 完成了单步,双步或三步跳。那就是最后 此举可能只是步骤 n-1 的单步跳跃,是两次 从步骤 n-2 跳一步,或从 n-3 跳三步。的 因此,到达最后一步的方法总数为 最后三个步骤中的每个步骤的数量
您正在正确考虑-
为什么不是这样的答案:添加这些路径的数量然后添加3? 由于如果您使用的是步骤n-1或n-2或n-3,则有3种方法 第n步?
这种基本情况的问题在于,仅当n> = 3时才适用。如果只有2个步骤,您显然不会加3。
让我们分解个别案例,了解这里的基本案例是什么。
n = 0
There are no stairs to climb.
Total number of ways = 0
n = 1
Total number of ways = 1StepHop from (n-1)
Number of ways to do 1StepHop from Step 0(n-1) = 1
Total number of ways = 1
n = 2
Total number of ways = 2StepHop from (n-2) + 1StepHop from (n-1)
Number of ways to do 2StepHop to reach Step 2 from Step 0(n-2) = 1
Number of ways to do 1StepHop to reach Step 2 from Step 1(n-1) = 1 (Previous answer for n=1)
Total number of ways = 1 + 1 = 2
n = 3
Total number of ways = 3StepHop from (n-3) + 2StepHop from (n-2) + 1StepHop from (n-1)
Number of ways to do 3StepHop to reach Step 3 from Step 0(n-3) = 1
Number of ways to do 2StepHop to reach Step 3 from Step 1(n-2) = 2 (From previous answer for n = 2)
Number of ways to do 1StepHop to reach Step 3 from Step 2 = 1 (From previous answer for n=1)
Total number of ways = 1 + 2 + 1 = 4
观察- 从上面可以看到,在每种情况下,我们都正确地考虑了最后一步。为 n-1 中的-> 1StepHop, n-2 和中的 2StepHop分别添加一个 n-3 中的3StepHop。
现在查看代码,如果 n == 0 时返回 1 的情况有点违反直觉,因为我们已经看到答案应该是<如果 n == 0 ,则为strong> 0 。 -
public static int countWaysDP(int n, int[] map) {
if (n < 0)
return 0;
else if (n == 0)
return 1; <------------- this case is counter-intuitive
else if (map[n] > -1)
return map[n];
else {
map[n] = countWaysDP(n - 1, map) + countWaysDP(n - 2, map) + countWaysDP(n - 3, map);
return map[n];
}
从观察结果中,您可以看到 n == 0 的反直观情况实际上是说明最后一步的情况- n-1中的 1StepHop , n-2 中的 2StepHop和 n-3 中的 3StepHop。
因此,仅在递归过程中使用 n == 0 大小写才有意义-仅当 n的初始值大于0 时才会发生。
对此问题的更完整解决方案可能是使用驱动程序方法,该方法可以在核心递归算法之外处理该情况-
int countWays(int n) {
if (n <= 0 ) return 0;
int[] map = new int[n+1];
for(int i = 0; i<n+1; i++){
map[i] = -1;
}
return countWaysDP(n, map);
}
希望这会有所帮助。
答案 1 :(得分:-1)
您可以在以下位置找到解决方案 https://github.com/CrispenGari/Triple-Step-Algorithim/blob/master/main.cpp。
int count_Ways(int n){
if(n<0){
return 0;
}else if(n==0){
return 1;
}else{
return count_Ways(n-1) +count_Ways(n-2) + count_Ways(n-3);
}
}
int main(){
cout<<"Enter number of stairs: ";
int n;
cin>>n;
cout<<"There are "<< count_Ways(n)<<" possible ways the child can run up
thestairs."<<endl;
return 0;
}