DFS+DP,最长下山路径

来源:互联网 发布:知乎 二手房 买卖合同 编辑:程序博客网 时间:2024/05/01 02:11

题干:

      输入n x m的矩阵表示山峰排布方式,只能从一个山峰到邻近的且比它低的山峰,步长为1,求最长路径。

思路:

     动态规划加深搜。

     方程:

                  F[i][j] = max{  F[i+1][j] , F[i-1][j]  , F[i][j+1]  , F[i][j-1] }  + 1;  这样写肯定是错的,不过可以初窥端倪。

                 每次求F[i][j]时,我们先开一个循环,找它周围四个方向的山峰,如果比它矮,则F[x][y]=F[x1][y1]+1;(这里的x1,y1是走了一步后到的山峰,在这之前要先判断是否越界),我们可以设一个中间变量max=1,如果得到的值比max大,则赋给max,最后在直接F[x][y]=max就行,注意,如果周围的山峰都比他高,那max还是1,所以最后的赋值操作是没错的。最后在main函数里,遍历F数组,找最大值就行了。


代码:

 #include <stdio.h>
#include <stdlib.h>
#include <string.h>


int num[120][120];
int F[120][120];
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
int n,m;


int dfs(int i,int j){
    int x,y,t,ans=1;
    if(F[i][j]>0)
        return F[i][j];
    for(t=0;t<4;t++)
    {
        x=i+dx[t];
        y=j+dy[t];
        if(x>0 && x<=n && y>0 && y<=m)
            if(num[i][j]>num[x][y])
               if(dfs(x,y) + 1 > ans)
                   ans = dfs(x,y) + 1;
    }
    F[i][j] = ans;
    return ans;
}


int main(){
    int cas,i,j,ans;
    scanf("%d",&cas);
    char s[50];
    while(cas--)
    {
        ans = 0;
        scanf("%s %d %d",s,&n,&m);
        memset(num,0,sizeof(num));
        memset(F,0,sizeof(F));
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
               scanf("%d",&num[i][j]);
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                dfs(i,j);
        for(i=1;i<=n;i++)
            for(j=1;j<=m;j++)
                if(F[i][j]>ans)
                    ans = F[i][j];
        printf("%s: %d\n",s,ans);
    }
    return 0;
}






0 0
原创粉丝点击