该问题具有最优子结构
因此可设状态为d[i][j],表示从(i,j)走可以得到一条长d[i][j]的路
状态转移方程
d[r][c] = max(d[nr][nc] + 1, d[r][c]); //(nr,nc)为移动后坐标
因此max(d[i][j]) (i,j)∈{(r,c)| 0≤r<R,0≤c<C}为最终答案
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
#define MAX 105
int mat[MAX][MAX];
int d[MAX][MAX];
int r, c;
int dr[] = { 1,-1,0,0 };
int dc[] = { 0,0,1,-1 };
bool is_inside(int R, int C)
{
return R >= 0 && R < r&&C >= 0 && C < c;
}
void dp(int r, int c)
{
for (int i = 0;i != 4;++i)
{
int nr = r + dr[i], nc = c + dc[i];
if (!is_inside(nr, nc))
continue;
if (mat[nr][nc] < mat[r][c])
{
if (d[nr][nc] == -1)
dp(nr, nc);
d[r][c] = max(d[nr][nc] + 1, d[r][c]);
}
}
d[r][c] = max(1, d[r][c]);
}
int main()
{
int n;
cin >> n;
while (n--)
{
memset(d, -1, sizeof(d));
memset(mat, 0, sizeof(mat));
string name;
cin >> name >> r >> c;
for (int i = 0;i != r;++i)
for (int j = 0;j != c;++j)
cin >> mat[i][j];
for (int i = 0;i != r;++i)
for (int j = 0;j != c;++j)
dp(i, j);
int maxn = 0;
for (int i = 0;i != r;++i)
for (int j = 0;j != c;++j)
{
if (d[i][j] > maxn)
{
maxn = d[i][j];
}
}
printf("%s: %d\n", name.c_str(), maxn);
}
return 0;
}