动态规划:洛谷 P1314 [SHOI2002]滑雪
洛谷 P1314 [SHOI2002]滑雪
考的是动态规划,一题普及/提高-的题,我以前用的是bfs做的,动态规划是如此的方便快捷美妙,就是这题要考虑动态规划的无后效性,所有要用 优先队列,从高度最小的开始DP,从低到高。
我的题解:
1 //洛谷 P1314 [SHOI2002]滑雪 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 struct xue 7 { 8 int x, y, data; 9 }a[10005]; 10 bool cmp(xue a, xue b) 11 { 12 return a.data < b.data; 13 }//因为动态规划很重要的一个特点就是无后效性,所以我们最好从高度最小的 14 //格子开始动规 所以我们要用结构体存储 并排序 用优先队列解决问题 15 int snow[101][101]; 16 int num[101][101]; 17 int mov[4][2] = { 0,1,1,0,-1,0,0,-1 };//建立移动数组 18 int main() 19 { 20 int n, m; 21 cin >> n >> m; 22 int k = 0; 23 for (int i = 1; i <= n; ++i) 24 for (int j = 1; j <= m; ++j) 25 { 26 cin >> snow[i][j]; 27 num[i][j] = 1;//先把每个点的num值初始化为0 自己到自己的的值是1 28 a[k].x = i;//存储一下数据 29 a[k].y = j; 30 a[k].data = snow[i][j]; 31 k++; 32 } 33 sort(a, a + k, cmp);//排序 从小到大 34 int newx, newy; 35 for (int i = 0; i < k; ++i)//遍历 36 { 37 for (int j = 0; j < 4; ++j)//向四个方向 38 { 39 newx = a[i].x + mov[j][0]; 40 newy = a[i].y + mov[j][1]; 41 if (newx >= 1 && newx <= n && newy >= 1 && newy <= m)//先判断坐标的合法性 42 { 43 if (a[i].data < snow[newx][newy])//四周的山更高时 44 num[newx][newy] = max(num[a[i].x][a[i].y] + 1, num[newx][newy]); 45 //重点 我一开始写的是num+= 后来发现这样写是错误的 46 //要比较判断一下 num[new][new]=的最优解是遍历的这座山的num+1还是本来! 47 } 48 } 49 } 50 int ans = 0; 51 for (int i = 1; i <= n; ++i) 52 for (int j = 1; j <= m; ++j) 53 { 54 ans = max(ans, num[i][j]); 55 } 56 cout << ans; 57 58 }
完美完成!