https://www.luogu.com.cn/problem/P1434
朴素算法:会TLE一个点
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=110;
int f[N][N],a[N][N],n,m;
bool vis[N][N];
int ans;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int dfs(int x,int y)
{
int res=0;
vis[x][y]=true;
int s=0;
for(int i=0;i<4;i++)
{
int tempx=x+dx[i];
int tempy=y+dy[i];
if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=m&&!vis[tempx][tempy])
{
if(a[tempx][tempy]<a[x][y])
{
memset(vis,0,sizeof vis);
s=dfs(tempx,tempy);
}
}
res=max(res,s);//求四个方向中最大的那一段路
}
return res+1;//加上本身的那一步
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
memset(vis,0,sizeof vis);
ans=max(ans,dfs(i,j));
}
}
cout<<ans<<endl;
return 0;
}
记忆化搜索优化:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=110;
int f[N][N],a[N][N],n,m;
bool vis[N][N];
int ans;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int dfs(int x,int y)
{
int res=0;
vis[x][y]=true;
int s=0;
for(int i=0;i<4;i++)
{
int tempx=x+dx[i];
int tempy=y+dy[i];
if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=m&&!vis[tempx][tempy])
{
if(a[tempx][tempy]<a[x][y])
{
if(f[tempx][tempy]) s=f[tempx][tempy];//如果当前之前搜过了直接返回
else
{
memset(vis,0,sizeof vis);
s=dfs(tempx,tempy);
}
}
}
res=max(res,s);
}
return res+1;
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
memset(vis,0,sizeof vis);
int t=dfs(i,j);
f[i][j]=t;//记录状态
ans=max(ans,t);
}
}
cout<<ans<<endl;
return 0;
}
进一步的记忆化搜索优化:
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=110;
int f[N][N],a[N][N],n,m;
bool vis[N][N];
int ans;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int dfs(int x,int y)
{
int res=0;
vis[x][y]=true;
int s=0;
for(int i=0;i<4;i++)
{
int tempx=x+dx[i];
int tempy=y+dy[i];
if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=m&&!vis[tempx][tempy])
{
if(a[tempx][tempy]<a[x][y])
{
if(f[tempx][tempy]) s=f[tempx][tempy];
else
{
memset(vis,0,sizeof vis);
s=dfs(tempx,tempy);
f[tempx][tempy]=s;
}
}
}
res=max(res,s);
}
return res+1;
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
memset(vis,0,sizeof vis);
int t=dfs(i,j);
f[i][j]=t;
ans=max(ans,t);
}
}
cout<<ans<<endl;
return 0;
}
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=110;
int f[N][N],a[N][N],n,m;
bool vis[N][N];
int ans;
int dx[4]={-1,0,1,0};
int dy[4]={0,1,0,-1};
int dfs(int x,int y)
{
int res=0;
vis[x][y]=true;
int s=0;
for(int i=0;i<4;i++)
{
int tempx=x+dx[i];
int tempy=y+dy[i];
if(tempx>=1&&tempx<=n&&tempy>=1&&tempy<=m&&!vis[tempx][tempy])
{
if(a[tempx][tempy]<a[x][y])
{
if(f[tempx][tempy]) s=f[tempx][tempy];
else
{
memset(vis,0,sizeof vis);
s=dfs(tempx,tempy);
f[tempx][tempy]=s;
}
}
}
res=max(res,s);
}
f[x][y]=res+1;
return f[x][y];
}
int main(void)
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
memset(vis,0,sizeof vis);
int t=dfs(i,j);
ans=max(ans,t);
}
}
cout<<ans<<endl;
return 0;
}