ACM/ICPC 之 DP初步(POJ1088-滑雪)

POJ1088-滑雪

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

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

 1 //经典DP-由高向低海拔滑雪-求最长路
 2 //Memory:372K    Time:32 Ms
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<algorithm>
 7 using namespace std;
 8 #define max(x,y) ((x)>(y)?(x):(y))
 9 #define MAX 105
10 int row, col, len;
11 int map[MAX][MAX];    //标准记录
12 int mov[4][2] = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
13 int d[MAX][MAX];    //dp[]
14 int ans;
15 /*各点属性*/
16 struct Node{
17     int x, y;    //坐标(x,y)
18     int value;    //海拔
19 }node[MAX*MAX];
20 bool operator < (const Node a,const Node b)
21 {
22     return a.value < b.value;
23 }
24 void DP()
25 {
26     ans = 0;
27     memset(d, 0, sizeof(d));
28     for (int i = 0; i < len; i++)
29     {
30         int x = node[i].x, y = node[i].y;
31         for (int j = 0; j < 4; j++)
32         {
33             int tx = x + mov[j][0];
34             int ty = y + mov[j][1];
35             if (tx >= 0 && tx < row && ty >= 0 && ty < col)
36             {
37                 if (map[x][y] > map[tx][ty])
38                     d[x][y] = max(d[x][y], d[tx][ty] + 1);
39             }
40             d[x][y] = max(1, d[x][y]);
41         }
42         ans = max(ans, d[x][y]);
43     }
44     return;
45 }
46 int main()
47 {
48     scanf("%d%d", &row, &col);
49     len = 0;
50     for (int i = 0; i < row; i++)
51     {
52         for (int j = 0; j < col; j++)
53         {
54             scanf("%d", &map[i][j]);
55             node[len].x = i;
56             node[len].y = j;
57             node[len++].value = map[i][j];
58         }
59     }
60     sort(node, node + len);    //将各点按照-升序-排列
61     DP();
62     printf("%d\n", ans);
63     return 0;
64 }

 

 

你可能感兴趣的:(ACM/ICPC 之 DP初步(POJ1088-滑雪))