【问题标题】:2D grid travel (Dynamic Programming) - recursive solution working but not memoized one2D 网格旅行(动态编程) - 递归解决方案工作但没有记忆一个
【发布时间】: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) 其中Cthe binomial coefficient
  • 您的gridTravelerMemo 不共享内存。 (但很可能与“边界错误”无关)
  • memogridTravelerMemo 中的一个局部变量;每次调用gridTravelerMemo 都会获得自己的副本。 memo.count(key) 始终为零,因为 memo 始终为空。
  • 你没有m == 1 &amp;&amp; n == 1m == 0 || n == 0的终止条件,就像你在gridTraveller中所做的那样。你不断地从mn 中减去1,直到它们最终变成一个巨大的值;然后你继续走直到堆栈溢出。
  • @IgorTandetnik memo 现在是全局的,函数 gridTravelerMemo() 是静态的,地址边界错误仍然存​​在。是的,您的其他二项式系数解决方案有效。

标签: c++ stl dynamic-programming graph-theory graph-algorithm


【解决方案1】:

你需要在函数gridTravelerMemo中添加一个breaker和初始化条件

更新:

另一个问题是,你每次都在初始化无序映射 gridTravelerMemo 函数,因此您还需要从函数中删除它并将其初始化为全局。

代码:

 #include<bits/stdc++.h>
unsigned gridTraveller(unsigned m, unsigned n);
unsigned gridTravelerMemo(unsigned m, unsigned n);
std::string keyConvertedToString(unsigned m, unsigned n);

std::unordered_map<std::string, int> memo;

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)
{

    const std::string key = keyConvertedToString(m,n);
    if (memo.count(key) > 0)
        return memo.at(key);
    if(m==0 || n==0) return 0;
    if(m==1 && n==1) return 1;
    memo[key] = gridTravelerMemo(m-1, n) + gridTravelerMemo(m, n-1);
    return memo.at(key);
}

【讨论】:

  • m&lt;0 不可能是真的,因为munsigned
  • 请注意,这与gridTraveller 完全相同,加上设置空地图并检查它是否确实为空的无意义的忙碌工作。 memo.count(key) 始终为零。
  • 不起作用;错误:警告:无符号表达式的比较
  • 字符串?嗯?你知道std::pair吗?
猜你喜欢
  • 2021-06-04
  • 2020-08-09
  • 1970-01-01
  • 2022-01-19
  • 2010-10-15
  • 2021-08-17
  • 2020-12-10
  • 2021-02-17
  • 2021-06-23
相关资源
最近更新 更多