思路
假设从( 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。
代码
1 2 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; }
|