单纯的 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());
}