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 之 经典动规(POJ1088-滑雪)
时间: 2024-12-10 10:38:05