动态规划:洛谷 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 }

 

 完美完成!

posted @ 2022-04-03 11:32  朱朱成  阅读(48)  评论(0编辑  收藏  举报