Description
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
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
一个人以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-…-3-2-1更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
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
思路
其实这道题可以直接dfs+记忆化完成,对于每一个位置,只有他四周的空格中有比它矮的才继续走
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
int a[1005][1005],n,s,m,b[1005][1005],qq[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int dfs(int x,int y)
{
if (b[x][y]!=0)
{
return b[x][y];
}
s++;
b[x][y]=1;
for (int i=0;i<4;i++)
{
int dx=x+qq[i][0],dy=y+qq[i][1];
if (dx<1||dx>n||dy<1||dy>m) continue;
if (a[dx][dy]<a[x][y]) b[x][y]=max(dfs(dx,dy)+1,b[x][y]);
}
return b[x][y];
}
int main()
{
scanf("%d%d",&n,&m);
int mx=0;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) scanf("%d",&a[i][j]);
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
mx=max(dfs(i,j),mx);
}
}
cout<<mx;
return 0;
}
当然我们也可以用动态规划完成,首先把每一个点从低到高排序,对于每一个点,如果它周围有比它小的点,那么求该点的最长路径,由于从低到高,所以可以证明每一个比该点低的点一定是最优的,满足最优子结构和无后效性。f[i][j]为第i,j个点的最长路径
f
[
i
]
[
j
]
=
m
i
n
(
f
[
i
−
1
]
[
j
]
,
f
[
i
]
[
j
−
1
]
,
f
[
i
+
1
]
[
j
]
,
f
[
i
]
[
j
+
1
]
)
(
在
该
点
可
以
达
到
的
点
中
选
)
(
1
<
=
i
<
=
n
,
1
<
=
j
<
=
m
)
f[i][j]=min(f[i-1][j],f[i][j-1],f[i+1][j],f[i][j+1])(在该点可以达到的点中选)(1<=i<=n,1<=j<=m)
f[i][j]=min(f[i−1][j],f[i][j−1],f[i+1][j],f[i][j+1])(在该点可以达到的点中选)(1<=i<=n,1<=j<=m)
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
int a[1005][1005],mx,c[1005][1005],n,m,qq[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct f{
int x,y,z;
} b[1000009];
void dp(int x,int y)
{
for (int i=0;i<4;i++)
{
int dx=x+qq[i][0],dy=y+qq[i][1];
if (dx<1||dx>n||dy<1||dy>m) continue;
if (a[dx][dy]<a[x][y]) c[x][y]=max(c[dx][dy]+1,c[x][y]);
}
return;
}
bool cmp(f a,f b)
{
return a.z<b.z;
}
int main()
{
scanf("%d%d",&n,&m);
int mx=0;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
b[i*m-m+j].x=i;
b[i*m-m+j].y=j;
b[i*m-m+j].z=a[i][j];
c[i][j]=1;
}
}
sort(b+1,b+1+n*m,cmp);
for (int i=1;i<=n*m;i++)
{
dp(b[i].x,b[i].y);
mx=max(mx,c[b[i].x][b[i].y]);
}
cout<<mx;
return 0;
}