为什么我的 Grid Traveler Memoization 仍然存在?

Why is my Grid Traveler Memoization still sticking?

我目前正致力于在 Grid Traveler 问题中实现记忆化。看起来它应该可以工作,但它仍然坚持在更大的情况下,如 (18,18)。我是不是漏掉了什么,或者地图不是解决此类问题的正确选择?

P.S。我在使用地图方面还是个新手。

    #include <iostream>
    #include <unordered_map>
    #include <string>
    using namespace std;

    uint64_t gridTravMemo(int m, int n, unordered_map<string, uint64_t>grid)
    {
        string key;

        key = to_string(m) + "," + to_string(n);
        if (grid.count(key) > 0)
            return grid.at(key);
        if (m == 1 && n == 1)
            return 1;
        if (m == 0 || n == 0)
            return 0;

        grid[key] = gridTravMemo(m-1, n, grid) + gridTravMemo(m, n-1, grid);
        return grid.at(key);
    }

    int main()
    {
        unordered_map<string, uint64_t> gridMap;

        cout << gridTravMemo(1, 1, gridMap) << endl;
        cout << gridTravMemo(2, 2, gridMap) << endl;
        cout << gridTravMemo(3, 2, gridMap) << endl;
        cout << gridTravMemo(3, 3, gridMap) << endl;
        cout << gridTravMemo(18, 18, gridMap) << endl;

        return 0;
    }

记忆搜索的要点是通过返回您之前计算的任何值来优化 运行宁时间。这样,您可以达到 O(N*M).

的 运行 时间,而不是蛮力算法

但是,您将 unordered_map<string, uint64_t>grid 作为参数传递给 depth-first 搜索。

您正在呼叫 grid[key] = gridTravMemo(m-1, n, grid) + gridTravMemo(m, n-1, grid); 这意味着您的搜索正分成两个分支。 然而,这两个分支中的grid是不同的。这意味着可以在两个不同的分支中访问相同的状态,从而导致运行时间更像O(2^(N*M)).

当您测试 18x18 网格时,这绝对 运行 不够快。

这相对容易修复。只需将 grid 声明为全局变量即可。这样它的值就可以在不同的分支之间使用。

尝试这样的事情:

    #include <iostream>
    #include <unordered_map>
    #include <string>
    using namespace std;

    unordered_map<string, uint64_t> grid;

    uint64_t gridTravMemo(int m, int n)
    {
        string key;

        key = to_string(m) + "," + to_string(n);
        if (grid.count(key) > 0)
            return grid.at(key);
        if (m == 1 && n == 1)
            return 1;
        if (m == 0 || n == 0)
            return 0;

        grid[key] = gridTravMemo(m-1, n) + gridTravMemo(m, n-1);
        return grid.at(key);
    }

    int main()
    {

        cout << gridTravMemo(1, 1) << endl;
        grid.clear()
        cout << gridTravMemo(2, 2) << endl;
        grid.clear()
        cout << gridTravMemo(3, 2) << endl;
        grid.clear()
        cout << gridTravMemo(3, 3) << endl;
        grid.clear()
        cout << gridTravMemo(18, 18) << endl;

        return 0;
    }