题目的意思就是一个人喜欢滑雪.但是滑雪只能从高处滑到低处.
然后给出一张图,图里的数字代表这个点的高度.
在途中找出最长的滑雪路线(只能上下左右划).
于是我们可以达到一个状态转移方程
d[ i ][ j ] 是指以 i , j 这个点作为终点的最大长度.
d[ i ] [ j ] = max { d[ ik] [jk] } (ik , jk 表示四个方向变化后的坐标 ,当然加进去比较的点必须满足不越界,并且那个比这个点大 .)
然后遍历每个点作为终点,找最大值.
AC代码 :
#include<stdio.h>
#include<string>
#include<iostream>
#include<string.h>
using namespace std;
const int N = 105 ;
int r,c;
int g[N][N];
int d[N][N];
int dirx[4] = {1 , -1 , 0 , 0} ;
int diry[4] = {0 , 0 , 1 , -1} ;
int dp(int x , int y) {
if(d[x][y] != -1) {
return d[x][y];
}
int dx,dy;
int m = 0;
for (int i = 0 ; i < 4 ;i++) {
dx = x + dirx[i];
dy = y + diry[i];
if (dx >= r || dx < 0 || dy >= c || dy < 0 || g[dx][dy] <= g[x][y]) {
continue;
}
if(dp(dx ,dy) > m)
m = d[dx][dy];
}
d[x][y] = m + 1;
return d[x][y] ;
}
int main () {
int t;
string name;
scanf("%d",&t);
while (t--) {
memset(d, -1 ,sizeof(d));
cin >> name;
scanf("%d%d",&r,&c);
for (int i = 0 ; i < r ;i++) {
for (int j = 0 ; j < c ;j++) {
scanf("%d",&g[i][j]);
}
}
int m = 0;
for (int i = 0 ; i < r ;i++) {
for (int j = 0 ; j < c ;j++) {
if (dp(i , j) > m)
m = d[i][j];
}
}
cout << name << ": ";
printf("%d\n",m);
}
}