题目大意:RXC大小的矩阵格网,每一格都赋有高度值。现从某一格出发,严格往低处走(即往高度减小的方向走),求满足这样条件的最长路径。
思路:1.很容易想到,从任意一个格出发都有4个方向(边缘处除外),即能求出多条路径,但最大值只有一种。
2.若从A点出发,需要经过B点,那么A点对应的最长路径中包含B点对应最长路径,即存在最优子结构。
因此,最终的思路可以确定为 dfs + dp, dfs搜索出各点为起点的最长路径并做标记备忘录供dp时查询。
#include <stdio.h>
int R,C;
int hei[101][101];
int flag[101][101];
int dp[101][101];
#define max(a,b) (((a) > (b)) ? (a) : (b))
void dfs(int i, int j, int h)
{
if(i-1 >=0 && hei[i-1][j] < hei[i][j]){
if(!flag[i-1][j]) dfs(i-1,j,hei[i][j]);
dp[i][j] = max(dp[i][j],dp[i-1][j]+1);
}
if(i+1<R && hei[i+1][j] < hei[i][j]){
if(!flag[i+1][j])dfs(i+1,j,hei[i][j]);
dp[i][j] = max(dp[i][j],dp[i+1][j]+1);
}
if(j-1>=0 && hei[i][j-1] < hei[i][j]){
if(!flag[i][j-1])dfs(i,j-1,hei[i][j]);
dp[i][j] = max(dp[i][j],dp[i][j-1]+1);
}
if(j+1<C && hei[i][j+1] < hei[i][j]){
if(!flag[i][j+1])dfs(i,j+1,hei[i][j]);
dp[i][j] = max(dp[i][j],dp[i][j+1]+1);
}
flag[i][j] = 1;
}
int main()
{
int i,j;
while (scanf("%d%d",&R,&C)==2){
for(i=0; i<R; i++){
for(j=0; j<C; j++){
scanf("%d",&hei[i][j]);
dp[i][j] = 1;
flag[i][j] = 0;
}
}
// dfs
for(i=0; i<R; i++){
for(j=0; j<C; j++){
dfs(i,j,10001);
}
}
// 找最大值
int longest = -1;
for(i=0; i<R; i++){
for(j=0; j<C; j++){
if(longest < dp[i][j])
longest = dp[i][j];
}
}
printf("%d\n",longest);
}
return 0;
}