NWU_ACM

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

解题思路:

如果从i,j可以顺着某侧滑的话:

1 dp[i][j] = max{dp[i-1][j],dp[i][j-1],dp[i+1][j],dp[i][j+1]} + 1
View Code

那么我们可以写出以下递归:

1 int dp(int i,int j)
2 {
3     for(i,j上侧,下侧,左侧,右侧)
4     if(该位置没有越界)
5     {
6         if(顺着该侧可以往下滑)
7             如果该侧位置可以滑行的距离(递归调用dp函数)大于dp[i][j],则把dp[i][j]改成该距离+1
8     }
9 }
View Code

所以依据上面的提示,就可以写出下面的代码:

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 int r,c,map[105][105],dp[105][105];
 7 int dx[]={-1,1,0,0};
 8 int dy[]={0,0,-1,1};
 9 int DP(int x,int y)
10 {
11     if(dp[x][y]!=0) return dp[x][y];
12     int MAX = 0;
13     for(int k=0;k<4;k++)
14             {
15                 int nx = x+dx[k];
16                 int ny = y+dy[k];
17                 if(map[nx][ny]<map[x][y]&&nx>=1&&ny>=1&&nx<=r&&ny<=c){
18                     if(DP(nx,ny)>MAX)
19                         MAX = DP(nx,ny);
20                 }
21             }
22             dp[x][y] = MAX+1;
23     return dp[x][y];
24 }
25 int main()
26 {
27     scanf("%d%d",&r,&c);
28     memset(dp,0,sizeof(dp));
29     memset(map,0,sizeof(map));
30     for(int i=1;i<=r;i++) for(int j=1;j<=c;j++) scanf("%d",&map[i][j]);
31     int MAX = 0;
32     for(int i=1;i<=r;i++)
33     {
34         for(int j=1;j<=c;j++)
35         {
36             if(DP(i,j)>MAX)
37                 MAX = DP(i,j);
38         }
39     }
40     printf("%d",MAX);
41 }
View Code

 

posted on 2017-03-05 19:19  NWU_ACM  阅读(200)  评论(0编辑  收藏  举报