poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088

 

题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径

 

分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关)。记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离。

dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+1,dp[x][y-1]+1,dp[x-1][y]+1,dp[x][y+1]+1);

#include<cstdio>
#include<queue>
#include<algorithm>
//dp[x][y]表示 (x,y)这个点的最长下滑路径
using namespace std;
const int maxn = 102;
using namespace std;
int n, m,bx,by,ans;
int G[maxn][maxn];
int dp[maxn][maxn];
int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};//这种图的搜索 可以把方向写在一个数组中 使代码更简洁
int dfs(int x, int y)
{
    if(dp[x][y])//如果之前已经有结果 那么直接使用
    {
        return dp[x][y];
    }
    for(int i = 0; i < 4;i++)
    {
        int tx = x,ty = y;
        tx += dir[i][0];
        ty += dir[i][1];
//        下面2个if都是排除非法情况
        if(tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
        if(G[tx][ty] >= G[x][y]) continue;
//        如果四周的点都比自己高 或者路径长没自己长 那么不更新 否则更新为四周的点+1
        dp[x][y] = max(dp[x][y],dfs(tx,ty)+1);
    }
    return dp[x][y];

}
int main()
{

    scanf("%d %d", &n,&m);
    for(int i = 0;i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            scanf("%d", &G[i][j]);

        }
    }
    ans = 0;
    for(int i =0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        dfs(i,j);
    }
    for(int i =0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
         ans = max(ans,dp[i][j]);
    }
    printf("%d",ans+1);//因为自己也算做一步 所以ans+1

    return 0;
}


 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值