Description
djw喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。
Input
第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。
Output
仅一行: 输出1个整数,表示可以滑行的最大长度。
Sample Input
5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9
Sample Output
25
首先谈思路,输入n,m,然后输入数组a,再用一个数组b储存每一个点到所能达到最低点的值,简单地说就是记忆化,再加上每一个点的搜索。
找到思路觉得简单的一批,果断一手Wa教会了我做人,记忆化过程中必须用到递归,即从某个点出发到达最低点,必须调用前一个点到最低点的距离,一直调用,直到走不动为止,走不动的时候便是该点所能达到的最低点,此时函数应返回1,在一次返回调用,算出所能达到的最大距离。
AC代码:
#include<iostream>
#include<algorithm>
using
namespace
std;
int
n,m,a[100][100],b[100][100];
int
c[4]={0,1,0,-1};
int
d[4]={1,0,-1,0};
int
dp(
int
x,
int
y)
{
if(b[x][y]!=1) //判断该点是否计算过,实现记忆化过程
{
return b[x][y];
}
int
k=0;
for
(
int
p=0;p<4;p++)
{
if
(x+c[p]<0 || y+d[p]>m-1 || x+c[p]>n-1 || y+d[p]<0) //防止超出边界
{
continue
;
}
else
{
if
(a[x+c[p]][y+d[p]]>a[x][y])
{
b[x][y]=max(b[x][y],dp(x+c[p],y+d[p])+1); //计算前一个点到最低点的距离
}
}
k=max(k,b[x][y]);
}
return
k;
}
int
main()
{
while
(cin>>n>>m)
{
int
count=0;
for
(
int
i=0;i<n;i++)
{
for
(
int
j=0;j<m;j++)
{
cin>>a[i][j];
b[i][j]=1;
}
}
for
(
int
i=0;i<n;i++)
{
for
(
int
j=0;j<m;j++)
{
count=max(count,dp(i,j));
}
}
cout<<count<<endl;
}
return
0;
}