思路
假设从( x, y )出发,并且从( x, y )出发所能走的最长路为 d[x][y],那么设想如果( x  - 1, y )的值(即题目所给的高度)要小于(x,y),那么d[x-1][y] + 1 有可能就是我们所要求的d[x][y],因为这条路是单向的,只可能从较小的(x-1, y)走向(x,y)。如果考虑四个方向,用(x’, y’)表示(x , y)上下左右四个方向,那么d[x][y] = max(d[x’][y’]) + 1,且 (x’, y’)上的值要小于(x, y)。那么从这个方程可以看出这实际上可以采用 DFS 加上 dp 的做法,或者称之为记忆化搜索。而 搜索 的终点则是某点(x, y)的四周都比他大,则返回 1。
代码
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 
 | 
 
 
 #include <bits/stdc++.h>
 
 using namespace std;
 
 typedef long long LL;
 typedef unsigned long long uLL;
 typedef pair<int, int> pr_int;
 
 int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
 const int MAXN = 100 + 40;
 int height[MAXN][MAXN], d[MAXN][MAXN];
 string name;
 int rows, cols;
 
 void read() {
 cin >> name >> rows >> cols;
 for (int i = 0; i < rows; ++i) {
 for (int j = 0; j < cols; ++j) {
 cin >> height[i][j];
 }
 }
 }
 
 int dp(int x, int y) {
 if (d[x][y] != -1) {
 return d[x][y];
 }
 int ans = 1;
 for (int i = 0; i < 4; ++ i) {
 int nx = x + dir[i][0], ny = y + dir[i][1];
 
 if (nx >=0 && nx < rows && ny >=0 && ny < cols && height[x][y] > height[nx][ny]) {
 ans = max(dp(nx, ny) + 1, ans);
 }
 }
 
 return d[x][y] = ans;
 }
 
 int main() {
 ios::sync_with_stdio(false);
 cin.tie(0);
 int T;
 cin >> T;
 while(T --) {
 read();
 int ans = 1;
 memset(d, -1, sizeof(d));
 for (int i = 0; i < rows; ++ i) {
 for (int j = 0; j < cols; ++ j) {
 ans = max(ans, dp(i, j));
 }
 }
 cout << name << ": " << ans << endl;
 }
 return 0;
 }
 
 |