dp+记忆化搜索。
告诉你一个山脉的一组高度,让你按照高度的降序滑行,要求能求出最大的滑行距离,即最长降序子序列。
但题目要求了滑行的方向只能为上下左右。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int Maxsize = 200;
int n,m;
int cnt[Maxsize][Maxsize],ans[Maxsize][Maxsize];
int main()
{
int dp(int a,int b);
int ncase;
char name[Maxsize*10];
cin>>ncase;
while(ncase--)
{
int maxt = -1;
cin>>name>>n>>m;
memset(cnt,-1,sizeof(cnt));
memset(ans,-1,sizeof(ans));
for(int i = 1 ;i <=n ;i++)
{
for(int j = 1; j <= m; j++)
{
cin>>cnt[i][j];
}
}
for(int i = 1; i <= n ; i++)
{
for(int j = 1; j <= m ; j++)
{
int t = dp(i,j);
if(maxt < t)
{
maxt = t;
}
}
}
printf("%s: %d\n",name,maxt);
}
return 0;
}
int dp(int i,int j)/*ans数组来确定在当前i,j坐标位置时所能滑行的最长距离*/
{
int maxx = 0;
if(ans[i][j] != -1 )
{
return ans[i][j];
}
if(j-1>=1)/*一次对上下左右四个方向进行判断,选出具有最优解的一个方向*/
{
if(cnt[i][j] >cnt[i][j-1])
{
if(maxx<dp(i,j-1))
{
maxx = dp(i,j-1);
}
}
}
if(j+1 <= m)
{
if(cnt[i][j] > cnt[i][j+1])
{
if(maxx < dp(i,j+1))
{
maxx = dp(i,j+1);
}
}
}
if(i+1 <= n)
{
if(cnt[i][j] > cnt[i+1][j])
{
if(maxx < dp(i+1,j))
{
maxx = dp(i+1,j);
}
}
}
if(i-1 >= 1)
{
if(cnt[i][j] >
cnt[i-1][j])
{
if(maxx < dp(i-1,j))
{
maxx = dp(i-1,j);
}
}
}
return ans[i][j] = maxx+1;/*返回并保持ans值*/
}