【发布时间】:2021-10-23 04:20:07
【问题描述】:
问题陈述 - 有一个尺寸为 m x n 的 2D 网格,你在左上角,当你只能向下或向右移动时,找出有多少种方法可以到达右下角。
代码使用无序映射,其中键是字符串,例如 "2,3" 、 "1,2" (树中的节点),它们的值是整数(到达该节点的方法数)。
以下是为递归函数 gridTraveller(2,3) 提供正确输出的代码;输出为 3。但是,当仅使用记忆函数 gridTravelerMemo(2,3) 编译时,会出现地址边界错误。
#include<bits/stdc++.h>
unsigned gridTraveller(unsigned m, unsigned n);
unsigned gridTravelerMemo(unsigned m, unsigned n);
std::string keyConvertedToString(unsigned m, unsigned n);
int main(int argc, char const *argv[])
{
//std::cout<<gridTraveller(2,3);
std::cout<<gridTravelerMemo(2,3);
return 0;
}
unsigned gridTraveller(unsigned m, unsigned n)
{
if (m == 1 && n == 1) return 1;
if (m == 0 || n == 0) return 0;
return gridTraveller(m-1, n) + gridTraveller(m, n-1);
}
std::string keyConvertedToString(unsigned m, unsigned n)
{
return (std::to_string(m) + ',' + std::to_string(n));
}
unsigned gridTravelerMemo(unsigned m, unsigned n)
{
std::unordered_map<std::string, int> memo;
const std::string key = keyConvertedToString(m,n);
if (memo.count(key) > 0)
return memo.at(key);
memo[key] = gridTravelerMemo(m-1, n) + gridTravelerMemo(m, n-1);
return memo.at(key);
}
尝试打印密钥并且它可以工作,因此该行可能有问题:
memo[key] = gridTravelerMemo(m-1, n) + gridTravelerMemo(m, n-1);
不知道是什么;请问有人吗?
【问题讨论】:
-
您不需要为此进行动态编程。您需要使
m+n-2步骤,其中m-1已关闭;这些可以按任何顺序完成。所以答案是C(m+n-2, m-1)其中C是the binomial coefficient -
您的
gridTravelerMemo不共享内存。 (但很可能与“边界错误”无关) -
memo是gridTravelerMemo中的一个局部变量;每次调用gridTravelerMemo都会获得自己的副本。memo.count(key)始终为零,因为memo始终为空。 -
你没有
m == 1 && n == 1和m == 0 || n == 0的终止条件,就像你在gridTraveller中所做的那样。你不断地从m和n中减去1,直到它们最终变成一个巨大的值;然后你继续走直到堆栈溢出。 -
@IgorTandetnik memo 现在是全局的,函数 gridTravelerMemo() 是静态的,地址边界错误仍然存在。是的,您的其他二项式系数解决方案有效。
标签: c++ stl dynamic-programming graph-theory graph-algorithm