题意:中文题,不解释.
分析:应该是很典型的DP吧,用记忆化搜索实现,因为每个map[i][j]的dp[i][j]都是相同的值,也就是重叠子问题,所以只要每个点都搜索出最长路径,也就是dp[i][j].最后双重循环暴力找到最长的路径输出就行了.
wa的原因:题意的情况想少了,写代码的时候忘记了判断与四周相等的情况.
AC的代码:
#include<iostream>
#include<string.h>
using namespace std;
int dp[150][150];
int used[150][150];
int map[150][150];
int count;
int r,c;
int dfs(int i,int j){
if(used[i][j])return dp[i][j];
if((i<0||j<0)||(i>=r||j>=c))return 0;
if(map[i][j]<=map[i+1][j]&&map[i][j]<=map[i-1][j]&&map[i][j]<=map[i][j+1]&&map[i][j]<=map[i][j-1]){
used[i][j]=1;
dp[i][j]=1;
}
if(map[i][j]>map[i+1][j]){
dp[i][j]=max(dp[i][j],dfs(i+1,j)+1);
used[i][j]=1;
}
if(map[i][j]>map[i-1][j]){
dp[i][j]=max(dp[i][j],dfs(i-1,j)+1);
used[i][j]=1;
}
if(map[i][j]>map[i][j+1]){
dp[i][j]=max(dp[i][j],dfs(i,j+1)+1);
used[i][j]=1;
}
if(map[i][j]>map[i][j-1]){
dp[i][j]=max(dp[i][j],dfs(i,j-1)+1);
}
used[i][j]=1;
if(dp[i][j]>count)count=dp[i][j];
return dp[i][j];
}
int main(){
while(cin>>r>>c){
count=1;
memset(dp,0,sizeof(dp));
memset(used,0,sizeof(used));
memset(map,0,sizeof(map));
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
cin>>map[i][j];
for(int i=0;i<r;++i)
for(int j=0;j<c;++j)
dfs(i,j);
cout<<count<<endl;
}
return 0;
}