分析:暴力搜索显然不行,看起来可以降维降序后求地形的LDS,不过因为要求地形空间连续的关系,最多只能用O(n^2)的dp算法,仍然会超时!正确的解法是: 记忆化搜索(dp+搜索),减少搜索中的重复子问题(当子问题A和子问题B存在子子问题C时,如果子子问题C的最优解已经被求出,那么子问题A或者是B只需要“查表”获得C的解,而不需要再算一遍C),由于每个顶点只访问一次,故时间复杂度为O(rc)
代码(1)
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAX_R = 105;
const int MAX_C = 105;
int r, c;
int h[MAX_R][MAX_C], dp[MAX_R][MAX_C];//dp[i][j]:从地形(i,j)出发可以滑行的最大长度
const int x[4] = { 1,0,-1,0 }, y[4] = { 0,1,0,-1 };
void read() {
cin >> r >> c;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
cin >> h[i][j];
}
}
}
int dfs(int i, int j) {
if (i <= 0 || i > r || j <= 0 || j > c) return 0;
if (dp[i][j]) return dp[i][j];
bool flag = false;
for (int t = 0; t < 4; t++) {
int turn_x = i + x[t];
int turn_y = j + y[t];
if (h[turn_x][turn_y] < h[i][j]) {
flag = true;
if (dp[turn_x][turn_y]) dp[i][j] = max(dp[turn_x][turn_y] + 1, dp[i][j]);
else dp[i][j] = max(dp[i][j], dfs(turn_x, turn_y) + 1);
}
}
if(!flag) dp[i][j] += 1; //周边的地形都比(i,j)大
return dp[i][j];
}
void solve() {
memset(dp, 0, sizeof(dp));
int ans = 0;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
ans = max(ans, dfs(i, j));
}
}
cout << ans << '\n';
}
int main() {
read();
solve();
return 0;
}
代码(2)
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAX_R = 105;
const int MAX_C = 105;
int r, c;
int h[MAX_R][MAX_C], dp[MAX_R][MAX_C];//dp[i][j]:从地形(i,j)周边出发可以滑行的最大长度
const int x[4] = { 1,0,-1,0 }, y[4] = { 0,1,0,-1 };
void read() {
cin >> r >> c;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
cin >> h[i][j];
}
}
}
int dfs(int i, int j) {
if (i <= 0 || i > r || j <= 0 || j > c) return -1;
if (dp[i][j]) return dp[i][j];
for (int t = 0; t < 4; t++) {
int turn_x = i + x[t];
int turn_y = j + y[t];
if (h[turn_x][turn_y] < h[i][j]) {
if (dp[turn_x][turn_y]) dp[i][j] = max(dp[turn_x][turn_y] + 1, dp[i][j]);
else dp[i][j] = max(dp[i][j], dfs(turn_x, turn_y) + 1);
}
}
return dp[i][j];
}
void solve() {
memset(dp, 0, sizeof(dp));
int ans = 0;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
ans = max(ans, dfs(i, j) + 1); //地形(i,j)不立刻被计算
}
}
cout << ans << '\n';
}
int main() {
read();
solve();
return 0;
}