【问题标题】:Number of ways in which you can climb a staircase with 1, 2 or 3 steps - memoization您可以通过 1、2 或 3 步爬楼梯的方式数量 - 记忆
【发布时间】:2021-09-18 19:49:00
【问题描述】:

我必须计算一个人一次可以走 1、2 或 3 步爬楼梯的方式数。我知道这样做的方法,例如f(n-1) + f(n-2) + f(n-3),但我想知道为什么在我的实现中(与上述不同)我没有得到正确的答案。我正在使用 for 循环。 问题是每次返回一个非零值但该值包含预先计算的答案,因此我的代码不使用它。我需要进行哪些更改?

#include <iostream>
#include <map>

using namespace std;
int nWays = 0;

int stepPerms(int n, map<int, int> &memo) {

    if (memo.find(n) != memo.end())
        return memo[n];
    if (n == 0)
        return 0;
    if (n < 0)
        return -1;
    for (int i = 1; i <= 3; i++) {
        int retVal = stepPerms(n - i, memo);
        if (retVal == 0)
            memo[n] = ++nWays;
    }
    return memo[n];
}

int main() {
    map<int, int> memo;
    cout << stepPerms(5, memo);//cout << stepPerms(3) << endl;
}

【问题讨论】:

  • 在以for (int i = 1; i &lt;= 3; i++) 开始的循环中,当n 为1 且i 为2 时,stepPerms(n - i, memo); 返回什么? stepPerms` 针对这种情况返回的值会导致错误的结果。这种情况的代码在哪里。为什么它返回-1?它应该返回什么?
  • 递归和全局状态是一个令人讨厌的组合。
  • 永远不要仅仅将问题描述为“我没有得到正确的答案”。始终说明观察到的程序行为和期望的行为。 (并且,如果程序接受输入,请说明重现问题的示例输入。)例如,说明“此程序生成输出‘4’,但正确的输出将是‘7’。”对于这个问题,您应该向stepPerms 显示几个可能的参数及其相应的期望结果,以便人们可以检查他们对您对问题的描述的理解,以便他们可以测试代码。
  • 句子“问题是每次返回一个非零值但该值包含预先计算的答案,因此我的代码不使用它。”不清楚。
  • 另外,当n 为零时,stepPerms 应该返回什么?有多少个序列中元素之和为零的序列?提示:如果一个序列是空的,那么其中的元素之和是多少?

标签: c++ dynamic-programming memoization


【解决方案1】:

我是这样解决的:

#include <iostream>
#include <map>

using namespace std;
map<int, int> memo;

int stepPerms(int n) {
    if (memo.find(n) != memo.end())
        return memo[n];
    if (n == 0)
        return 0;
    if (n == 1)
        return 1;
    if (n == 2)
        return 2;
    if (n == 3)
        return 4;
    for (int i = 1; i <= 3; i++)
        memo[n] += stepPerms(n - i);
    return memo[n];
}

int main() {
    cout << stepPerms(27);
}

【讨论】:

  • 对于基本情况,您实际上只需要if (n &lt;= 0) return n == 0;(0 表示负n,1 表示零)。
猜你喜欢
  • 2021-12-17
  • 2020-11-09
  • 1970-01-01
  • 2013-02-25
  • 1970-01-01
  • 1970-01-01
  • 2015-10-11
  • 1970-01-01
  • 2014-01-19
相关资源
最近更新 更多