很经典的记忆化搜索题。设状态dp[i][j]为图中第i行第j个坐标所能到达的最远距离,然后用dfs进行记忆化搜索即可。此题同时可以看成是一个二维的序列,找出其中的最长递减子序列。
以下是用记忆化搜索方法做出的代码;
- #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int M=110;
const int inf=1<<29;
int max(int a,int b) {return a>b?a:b;} - int dir[4][2]={-1,0,1,0,0,-1,0,1};
int dp[M][M];
int map[M][M];
int r,c; - bool check(int a,int b)
{
if(0<=a && a<r && 0<=b && b<c)
return true;
else
return false;
} - void dfs(int x,int y)
{
int i,j;
for(i=0;i<4;i++)
{
int x1=x+dir[i][0];
int y1=y+dir[i][1];
if(check(x1,y1) && map[x][y]>map[x1][y1])
{
if(dp[x1][y1]==1)
{
dfs(x1,y1);
dp[x][y]=max(dp[x][y],dp[x1][y1]+1);
}
else
{
dp[x][y]=max(dp[x][y],dp[x1][y1]+1);
}
}
}
} - int main()
{
while(scanf("%d%d",&r,&c)==2)
{
int i,j,k;
int ans=0;
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
scanf("%d",&map[i][j]);
dp[i][j]=1;
}
}
for(i=0;i<r;i++)
{
for(j=0;j<c;j++)
{
if(dp[i][j]==1)
{
for(k=0;k<4;k++)
{
int x=i+dir[k][0];
int y=j+dir[k][1];
if(check(x,y) && map[i][j]>map[x][y])
{
if(dp[x][y]==1)
{
dfs(x,y);
dp[i][j]=max(dp[i][j],dp[x][y]+1);
}
else
{
dp[i][j]=max(dp[i][j],dp[x][y]+1);
}
}
}
}
if(dp[i][j]>ans) ans=dp[i][j];
}
}
printf("%d/n",ans);
}
return 0;
}
这里有个牛人的链接,讲的就是看成最长递减子序列的解法:
http://www.cppblog.com/abilitytao/archive/2010/11/25/74271.html