dfs过程中拿一个数组记录每一步的答案,这样就不需要重复计算其中的某一步,减小计算量
简单来说就是对dfs的优化
如题:
普通思路就是写dfs把每个点搜一遍,找到下一个比原来点小的点,但是这样写会超时,应该其中的点可能不止计算过一次,举个栗子
1 2 3
4 5 6
7 8 9
从“9”到“1”,可以从“9”-“6”-“3”-“2”-“1”,这样就会判断递归4次,然后还得从1逐层进行dfs,如果数据量较大,就很容易超时,所以只需要将每一个点到最低点的距离储存起来,这样每个点只需要处理为比自己小的点+1,比如从“9”到“1”就只需要“9”-“8”+1或者“9”-“6”+1(好规),先将数组赋值为其中一个,再跟另外一个进行比较,较大的就是ans。
我拿vis数组作为储存某一个点的数组,每次遇到新的点,先赋值为1进行标记,然后再dfs搜索比他小的点,直到搜到最小的点,赋值为1,然后依次往上+1,如果遇到的是储存过数值的点,那么就直接返回这个点的值,避免重复计算
具体看代码
#include<bits/stdc++.h>//懂得都懂
using namespace std;//没什么好说的
int r,c,ans=0;//r是列数(对应x),c是行数(对应y),切记不能搞反
int a[600][600];//储存每个点的高度
int vis[600][600];//储存每个点到最低点的距离,也就是答案
int dx[4]={0,0,1,-1};//x的四个方向
int dy[4]={1,-1,0,0};//y的四个方向
int dfs(int x,int y)//简简单单的dfs
{
if(vis[x][y]!=0)//避免重复计算
{
return vis[x][y];
}
s[x][y]=1;//先标记为1,如果有比它还小的点,再进行赋值
for(int i=0;i<4;i++)//四个方向
{
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>0&&xx<=r&&yy>0&&yy<=c&&a[x][y]>a[xx][yy])//判断是否出界和寻找比(x,y)小的(xx,yy)
{
dfs(xx,yy);//将这一点以下的所有符合上述条件的点标记为1或者赋值为上一个点(比它小的点)+1
vis[x][y]=max(vis[x][y],vis[xx][yy]+1);赋值
}
}
return vis[x][y]; 返回该点到最低点的距离
}
int main()
{
cin>>r>>c;输入
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
cin>>a[i][j];还是输入
}
}
for(int i=1;i<=r;i++)
{
for(int j=1;j<=c;j++)
{
ans=max(ans,dfs(i,j));处理,判断(i,j)点所储存的距离和ans的大小,用ans储存答案,使得答案永远是较大的那一个
}
}
cout<<ans;输出结束
return 0;
}