滑雪(记忆化搜索)

思路:

(1)f[i][j]表示以(i,j)为起点的任意方案中的最长路;

(2)将其拆分为下一步走上下左右四个方向;

(3)由于是按第一步进行分类而不是最后一步,考虑递归求dp(i,j),用f[i][j]存储答案,如果已经求出来,直接返回即可;反之f[i][j]先初始化为1,四个方向逐一尝试,如果在范围内,且下一步高度小于(i,j);那么就更新res,dp(ei,ej) + 1进行更新,即下一步最远距离 +1;得到res后返回即可。

(4)注意f先初始化为-1方便判断是否求出答案。

代码:

#include

using namespace std;

int dx[] = {0,0,1,-1},dy[] = {1,-1,0,0};

const int N = 310;
int f[N][N],h[N][N];
int n,m;
int dp(int x,int y)
{
    if(f[x][y] != -1) return f[x][y];
    
    f[x][y] = 1;
    for(int i = 0;i < 4;i ++)
    {
        int ex = dx[i] + x,ey = dy[i] + y;
        if(ex >= 1 && ex <= n && ey >= 1 && ey <= m && h[x][y] > h[ex][ey])
        f[x][y] = max(f[x][y],dp(ex,ey) + 1);
    }
    
    return f[x][y];
}

int main()
{

    cin >> n >> m;
    
    for(int i = 1;i <= n;i ++)  
        for(int j = 1;j <= m;j ++)
            cin >> h[i][j];
    
    memset(f,-1,sizeof f); 
    
    int res = 0;
    for(int i = 1;i <= n;i ++)
        for(int j = 1;j <= m;j ++)
            res = max(res,dp(i,j));
    
    cout << res << endl;
    
    return 0;
}

你可能感兴趣的:(算法,动态规划,图论)