题目链接
思路
递归型dp,记忆化搜索。
要找一条最长的上升序列,那么可以用一个数组dp[][],dp[i][j]表示从(i,j)开始的最长上升序列的长度,由于这是在一个二维矩阵里的状态转移,所以不是很容易确定递推的方向,可以选择递归型dp,也就是记忆化搜索。
#include<iostream>
#include<cstring>
using namespace std;
const int maxn=120;
int mat[maxn][maxn];
int dp[maxn][maxn];//代表从(i,j)开始的最长上坡
int n,m;
int dir[4][2]={1,0,-1,0,0,1,0,-1};
//记忆化搜索,不用考虑dp方向问题
int dfs(int x,int y)
{
if(dp[x][y])//如果已经搜过
return dp[x][y];//直接返回
int res=1;//每个点的dp值至少为1
for(int i=0;i<4;i++)
{//向四个方向扩展
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx>0&&xx<=n&&yy>0&&yy<=m&&mat[xx][yy]>mat[x][y])
res=max(dfs(xx,yy)+1,res);//选择四个方向的最大值
}
dp[x][y]=res;//确定最大值后,别忘了在返回之前记录该值
return res;
}
int main()
{
int i,j;
while(cin>>n>>m)
{
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>mat[i][j];
int ans=0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
ans=max(dfs(i,j),ans);//返回最大值
cout<<ans<<endl;
}
return 0;
}