ACM/ICPC 之 简单DP-记忆化搜索与递推(POJ1088-滑雪)

递推型DP

将每个滑雪点都看作起点,从最低点开始逐个由四周递推出到达此点的最长路径的长度,由该点记下。

理论上,也可以将每一点都看作终点,由最高点开始计数,有兴趣可以试试。

//经典DP-由高向低海拔滑雪-求最长路
//Memory:372K    Time:16 Ms
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

#define MAX 105

int row, col, len;
int map[MAX][MAX];    //标准记录
int mov[4][2] = { { 1, 0 },{ -1, 0 },{ 0, 1 },{ 0, -1 } };
int d[MAX][MAX];    //dp[]
int ans;

/*各点属性*/
struct Node {
    int x, y;    //坐标(x,y)
    int value;    //海拔
}node[MAX*MAX];

bool operator < (const Node a, const Node b)
{
    return a.value < b.value;
}

void DP()
{
    ans = 0;
    memset(d, 0, sizeof(d));
    for (int i = 0; i < len; i++)
    {
        int x = node[i].x, y = node[i].y;
        for (int j = 0; j < 4; j++)
        {
            int tx = x + mov[j][0];
            int ty = y + mov[j][1];
            if (tx >= 0 && tx < row && ty >= 0 && ty < col)
            {
                if (map[x][y] > map[tx][ty])
                    d[x][y] = max(d[x][y], d[tx][ty] + 1);
            }
            d[x][y] = max(1, d[x][y]);
        }
        ans = max(ans, d[x][y]);
    }
    return;
}

int main()
{
    scanf("%d%d", &row, &col);
    len = 0;
    for (int i = 0; i < row; i++)
    {
        for (int j = 0; j < col; j++)
        {
            scanf("%d", &map[i][j]);
            node[len].x = i;
            node[len].y = j;
            node[len++].value = map[i][j];
        }
    }
    sort(node, node + len);    //将各点按照-升序-排列
    DP();
    printf("%d\n", ans);
    return 0;
}

 

 

 

 

记忆化搜索型DP

  不必排序,解法和思路也相对更加清晰

  

 1 //经典DP-由高向低海拔滑雪-求最长路
 2 //Memory:252K    Time:16 Ms
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 using namespace std;
 7 
 8 #define max(x,y) ((x)>(y)?(x):(y))
 9 #define MAX 105
10 
11 int row, col;
12 int map[MAX][MAX];    //标准记录
13 int mov[4][2] = { { 1, 0 },{ -1, 0 },{ 0, 1 },{ 0, -1 } };
14 int d[MAX][MAX];    //distance
15 int ans;
16 
17 int DFS(int x, int y)
18 {
19     if (d[x][y]) return d[x][y];
20 
21     for (int i = 0; i < 4; i++)
22     {
23         int tx = x + mov[i][0];
24         int ty = y + mov[i][1];
25         if (tx >= 0 && tx < row && ty >= 0 && ty < col)
26             if (map[tx][ty] < map[x][y])    //向下滑雪
27                 d[x][y] = max(DFS(tx, ty) + 1, d[x][y]);
28     }
29 
30     ans = max(d[x][y], ans);
31     return d[x][y];
32 }
33 
34 int main()
35 {
36     scanf("%d%d", &row, &col);
37 
38     for (int i = 0; i < row; i++)
39         for (int j = 0; j < col; j++)
40             scanf("%d", &map[i][j]);
41 
42     memset(d, 0, sizeof(d));
43     for (int i = 0; i < row; i++)
44         for (int j = 0; j < col;j++)
45             DFS(i,j);
46 
47     printf("%d\n", ans + 1);
48     return 0;
49 }

 

    原文作者:Inkblots
    原文地址: https://www.cnblogs.com/Inkblots/p/5186091.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞