【QAQ】codevs滑雪和记忆化搜索的小经验

戳我←

题目描述 Description

trs喜欢滑雪。他来到了一个滑雪场,这个滑雪场是一个矩形,为了简便,我们用r行c列的矩阵来表示每块地形。为了得到更快的速度,滑行的路线必须向下倾斜。
例如样例中的那个矩形,可以从某个点滑向上下左右四个相邻的点之一。例如24-17-16-1,其实25-24-23…3-2-1更长,事实上这是最长的一条。

输入描述 Input Description

输入文件

第1行: 两个数字r,c(1<=r,c<=100),表示矩阵的行列。
第2..r+1行:每行c个数,表示这个矩阵。

输出描述 Output Description

输出文件

仅一行: 输出1个整数,表示可以滑行的最大长度。

样例输入 Sample Input

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

样例输出 Sample Output

25

第一次打了个手打队列的宽搜,居然A了四个点嘿嘿嘿嘿嘿

orz57级wzd和wyh两个DP大佬

第一道记忆化搜索的题目。

思路是以每一个点为起点进行dfs,用dp数组记录下每次搜到的最长路

一开始傻傻的认为不同起点时搜到的每个点的最长路是不一样的QAAAQ

嘛,递归就是相同的过程一层层算下去

既然一开始要求最优解的话,那程序得到的每一层结果也一定是最优的

也可以理解成滑到那里忽然翻车了滑到的最长路径是多少23333

这样,当搜到一个节点,发现已经搜到过他的最长路,那就直接调用

已经知道翻车前最多滑多远了,爬起来继续滑还能滑多远呢23333

#include
#include
using namespace std;
const int MAXN = 1000 + 1;
int map[MAXN][MAXN],dp[MAXN][MAXN],maxx;
int mu[] = {0,-1,1,0},
    mr[] = {1,0,0,-1};
int dfs(int k,int j)
{
    if(dp[k][j]) return dp[k][j];
    int ans = 1;
    for(int i = 0; i < 4; i ++)
    {
        int x = k + mu[i] ;
        int y = j + mr[i] ;
        if(map[x][y] > map[k][j])
            ans = max(ans, dfs(x, y) + 1);
    }
    return dp[k][j] = ans;
}
int m,n;
int main()
{
    cin >> m >> n;
    for(int i = 1; i <= m; i ++)
        for(int j = 1; j <= n;j ++)
            cin >> map[i][j];
    for(int i = 1; i <= m; i ++)
        for(int j = 1; j <= n;j ++)
        {
            dp[i][j] = max(dfs(i,j),dp[i][j]);
            maxx = max(maxx, dp[i][j]);
        }
    cout << maxx;
    return 0;
}

你可能感兴趣的:(错题记录)