记忆化搜索之滑雪问题

题目链接;

http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=10

题目大意:就是给你一个矩阵,每一次只能往四个方向移动,并且下一步到达的方块上的数值都必须必上一次的小,问你怎样走才能走的步数最多。

具体思路:就是使用dfs,我觉得记忆化搜索和搜索的不同就是,记忆化搜索已经走过的值直接返回就可以了,不需要再进行计算。

代码:

#include<bits/stdc++.h>
using namespace std;
#define maxn  105

int a[105][105];
int dp[105][105];
int n,m;
int w[2][4]= {{1,-1,0,0},{0,0,1,-1}};
bool judge(int s1,int s2)
{
    if(s1>=1&&s1<=n&&s2>=1&&s2<=m)
        return true;
    return false;
}
int f(int t1,int t2)
{
    if(dp[t1][t2])
        return dp[t1][t2];//如果已经访问过,就退出来
    for(int i=0; i<4; i++)
    {
        int  xx=t1+w[0][i];
        int  yy=t2+w[1][i];
        if(judge(xx,yy))
        {
            if(a[t1][t2]>a[xx][yy])
            {
                int temp=f(xx,yy);
                dp[t1][t2]=dp[t1][t2]>temp?dp[t1][t2]:temp+1;//坑点,一定要注意大小关系,还有相等的时候。
            }
        }
    }
    return dp[t1][t2];
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>n>>m;
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                cin>>a[i][j];
            }
        }
        memset(dp,0,sizeof(dp));
        int ans=0;
        for(int i=1; i<=n; i++)//从多个起点开始走,不能只是从一个
        {
            for(int j=1; j<=m; j++)
            {
                ans=max(ans,f(i,j));
            }
        }
        cout<<ans+1<<endl;//加上本身
    }
    return 0;
}
 

猜你喜欢

转载自blog.csdn.net/let_life_stop/article/details/81128158