dp动规思想结合搜索,再搜索的过程中对搜索到过的最优子结构进行记录,当下次再递归搜索到时直接访问停止递归,以防止重复的拓扑搜索。
记忆化搜索是对dp的扩充,当dp情况多样难以枚举时,可以考虑结合搜索处理
#include<iostream>
#include<cstring>
#include<vector>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int nn=1e5+50;
const double eps=1e-6;
inline int read() {
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
return x*f;
}
inline void write(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,m;
int mp[105][105];
int dp[105][105];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int dfs(int x,int y)
{
if(dp[x][y])
return dp[x][y];
dp[x][y]=1;
for(int i=0;i<=3;++i)
{
int xx,yy;
xx=x+dx[i],yy=y+dy[i];
if(xx<1||xx>n||yy<1||yy>m)
continue;
if(mp[x][y]>mp[xx][yy])
{
dfs(xx,yy);
dp[x][y]=max(dp[x][y],dp[xx][yy]+1);
}
}
return dp[x][y];
}
int main()
{
n=read();
m=read();
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
mp[i][j]=read();
}
int ans=-1;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=m;++j)
{
ans=max(ans,dfs(i,j));
//cout<<dfs(i,j)<<" ";
}
//cout<<endl;
}
cout<<ans;
return 0;
}
附加一个路径记录输出
void pri(int x) { if(pre[x]==0) { cout<<x; return ; } pri(pre[x]); cout<<" "<<x; }