18. 小U的最大连续移动次数问题 | 豆包 MarsCode 刷题

102 阅读1分钟

单纯的 DFS 觉得不保险,于是加了个记忆化。

此外,为了写代码方便,可以规定第一步必须是下坡,对原来的 a 数组搜一次,对 a 中的所有值取相反数后再搜一次。

第一次交的时候本来应该用transform的地方写成了for_each,看来不熟悉这些高级的东西真的不能乱写。

代码(C++):

#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
#include <functional>
#include <unordered_map>
using namespace std;

class Searcher {
    const vector<vector<int>>& a;
    int m, n;
    vector<bool> visited;
    unordered_map<vector<bool>, unique_ptr<vector<vector<bool>>>> memo;
    int maxval;
    void Dfs(int x, int y, int val) {
        if (memo.find(visited) == memo.end()) {
            memo[visited] =
                make_unique<vector<vector<bool>>>(m, vector<bool>(n));
        }
        vector<bool>& memo_t = (*memo[visited])[x];
        if (memo_t[y]) {
            return;
        }
        memo_t[y] = true;
        maxval = max(maxval, val);
        const int a_cur = a[x][y];
        const bool flag = val & 1;
        const int dx[] = {-1, 0, 1, 0};
        const int dy[] = {0, 1, 0, -1};
        for (int k = 0; k < 4; ++k) {
            int x2 = x + dx[k], y2 = y + dy[k];
            if (x2 >= 0 && x2 < m && y2 >= 0 && y2 < n) {
                int id = x2*n + y2;
                if (visited[id] == false &&
                    (flag ? (a[x2][y2] > a_cur) : (a[x2][y2] < a_cur))) {
                    visited[id] = true;
                    Dfs(x2, y2, val + 1);
                    visited[id] = false;
                }
            }
        }
    }

public:
    Searcher(const vector<vector<int>>& a_, int m_, int n_) :
        a(a_), m(m_), n(n_), visited(m * n), maxval(0) {}
    int Search() {
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                int id = i*n + j;
                visited[id] = true;
                Dfs(i, j, 0);
                visited[id] = false;
            }
        }
        return maxval;
    }
};

int solution(int m, int n, vector<vector<int>>& a) {
    int tmp = Searcher(a, m, n).Search();
    for (auto& vec : a) {
        transform(vec.begin(), vec.end(), vec.begin(), negate<int>());
    }
    return max(tmp, Searcher(a, m, n).Search());
}