描述
给定一个n \times m \n×m 的矩阵,矩阵中的数字表示滑雪场各个区域的高度,你可以选择从任意一个区域出发,并滑向任意一个周边的高度严格更低的区域(周边的定义是上下左右相邻的区域)。请问整个滑雪场中最长的滑道有多长?(滑道的定义是从一个点出发的一条高度递减的路线)。
(本题和矩阵最长递增路径类似,该题是当年NOIP的一道经典题)
数据范围: 1 \le n,m \le 100 \1≤n,m≤100 ,矩阵中的数字满足 1 \le val \le 1000 \1≤val≤1000
输入描述:
第一行输入两个正整数 n 和 m 表示矩阵的长宽。
后续 n 行输入中每行有 m 个正整数,表示矩阵的各个元素大小。
输出描述:
输出最长递减路线。
示例1
输入:
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
复制输出:
25
复制说明:
从25出发,每次滑向周边比当前小 1 的区域。 25->24->23->22->......->1
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int a[105][105];
int dp[105][105];
int idx[105][105];
int direction[4][2]={
{-1,0},{0,1},{1,0},{0,-1}
};
int n,m;
int find(int x,int y)
{
idx[x][y]=1;
int maxx=0;
for(int i=0;i<4;i++)
{
int x1=direction[i][0]+x;
int y1=direction[i][1]+y;
if(a[x][y]<a[x1][y1]&&x1>=1 && x1<=n &&y1>=1&&y1<=m)
{
if(idx[x1][y1]==-1)
{
dp[x1][y1]=find(x1,y1);
}
if(dp[x1][y1]>maxx)
{
maxx=dp[x1][y1];
}
}
dp[x][y]=maxx+1;
}
return dp[x][y];
}
int main()
{
memset(idx,-1,sizeof(idx));
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
}
int maxx=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
maxx=max(maxx,find(i,j));//表示从ij处出发最大下降的长度
}
}
printf("%d\n",maxx);
return 0;
}