http://poj.org/problem?id=1088

  这是一道dp入门题,不过我一直没想明白应该怎么dp。今天,在做自己学校oj的算法基础题时看到这题,标注着dp的分类,加上我一直都比较喜欢做dp题,于是我就决心今晚要把这道入门题切了。

  题目是中文的,题目大意就免了吧……

  晚上做dp题的时候,我先是看见类似这题的一维单调增子序列,那题轻松AC了。但是,面对这个我隔了很长时间没想的二维dp题,我想了很久都想不到怎么dp。因为这题在我们学校的oj里是全部计算机专业都要知道怎么做的,所以题目下面有详细的解释,而且觉得那个题解是相当的浅显易懂。

下面是那个解释:

动规算法思路:
f矩阵与原高度矩阵一样大小,f(i,j)表示从(i,j)位置开始滑,可以获得的最大滑道的长度。算法步骤:
(1)将高度矩阵从低到高排序;
(2)按滑点从低到高依次计算最长滑道的长度,存于f(i,j)。
(3)f(i,j)中的最大值即原题所求。

  我依据它的描述以及我对这题的了解,解释一遍:  我们需要的是一个用来储存原本高度的二维数组,一个用来记忆dp状态的数组,以及一个储存高度以及该高度所在的坐标的结构体数组。先说明一下,我是为了方便自己,所以除了结构体数组外其他两个数组都是开大了的。因为poj的题目中数据是0<=h<=10000,所以我用-1作为图的边界条件,dp数组正常清零。为了方便遍历四个邻接的坐标,所以我定义了四个方向向量。    读入数据的时候,数据要被处理,放到相应的结构类型中。  然后,在核心处理前,我们的dp需要一个高度单调增大的,但是对应的坐标不会改变。结构体整块的数据移动就可以保留上述预处理的高度块的坐标。这里可以直接用qsort进行对高度的快排。这个预处理是后面dp的关键。    在预处理后,由低到高处理每个高度块所指示的坐标。对于每一个坐标,搜索该坐标周围的dp最大值(dp值的含义是从该点出发,最长可以滑多远),那么被处理的高度块其dp值就是上述最大值加一。然后,为什么可以这样做就是理解整道题的关键。  可能会有人有这样的疑问,在处理的时候刚开始周围的点不是还没知道dp值吗?为什么也可以直接利用?  解答这个问题的关键就在于,我们刚开始的时候,dp矩阵已经清零。假设从第一个坐标开始,显然,这个坐标是最矮的高度块所对应的坐标,所以在这周围四块不存在比它矮的那么一块,所以它的dp值是1。同时,我们观察到,这时周围四块的dp值都是0,所以这块必定会变为1。其他的也同理,如果周围存在比当前块高的块,那么这个块肯定是还没被赋值的,也就是默认的0。就是说,当前块无法继承这个比自己要高的块的dp值。此时为0是合理的!    找到所有dp值中的最大值后输出。

  这题我wa了几次,主要是刚开始没想到周围的高度块是允许比当前的大的,所以一个大小符号,导致我浪费了不少时间。  
下面是我的代码:
View Code

 1 #include "stdio.h"
 2 #include "string.h"
 3 #include "math.h"
 4 #include "stdlib.h"
 5
 6 #define Reset(a) memset(a, 0, sizeof(a))
 7 #define MAX 1000000000
 8
 9 int dir[4][2]={{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
10
11 struct high
12 {
13     int x, y;
14     int h;
15 };
16
17 int cmp(const void *_a, const void *_b)
18 {
19     struct high a=*(struct high *)_a;
20     struct high b=*(struct high *)_b;
21
22     return a.h-b.h;
23 }
24
25 int main()
26 {
27     int n, m;
28     while (~scanf("%d%d", &n, &m))
29     {
30         int h[n+2][m+2], dp[n+2][m+2];
31         struct high rec[n*m];
32
33         memset(h, 255, sizeof(h));
34         for (int i=1; i<=n; i++)
35             for (int j=1; j<=m; j++)
36             {
37                 scanf("%d", &h[i][j]);
38                 rec[(i-1)*m+j-1].h=h[i][j];
39                 rec[(i-1)*m+j-1].x=i;
40                 rec[(i-1)*m+j-1].y=j;
41             }
42         Reset(dp);
43         qsort(rec, n*m, sizeof(struct high), cmp);
44         int ans=0;
45         for (int i=0, tmp=n*m; i<tmp; i++)
46         {
47             int max=0;
48
49             for (int j=0; j<4; j++)
50             {
51                 if (max < dp[rec[i].x-dir[j][0]][rec[i].y-dir[j][1]]+1
52                     && h[rec[i].x-dir[j][0]][rec[i].y-dir[j][1]]!=h[rec[i].x][rec[i].y])
53                     max = dp[rec[i].x-dir[j][0]][rec[i].y-dir[j][1]]+1;
54                 dp[rec[i].x][rec[i].y] = max;
55             }
56             if(ans<max)
57                 ans=max;
58         }
59 /**
60         for (int i=1; i<=n; i++)
61         {
62             for (int j=1; j<=m; j++)
63                 printf("%4d ", dp[i][j]);
64             puts("");
65         }
66 /**/
67         printf("%d\n", ans);
68     }
69
70     return 0;
71 }


 
 

转载于:https://www.cnblogs.com/LyonLys/archive/2012/04/27/poj_1088_Lyon.html

poj 1088 滑雪 详解相关推荐

  1. POJ 1088 滑雪(输出对比)

    http://poj.org/problem?id=1088 滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 68159 ...

  2. poj 1088 滑雪(线性DP)

    滑雪 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 81553   Accepted: 30437 Description ...

  3. poj 1088 滑雪 (dp)

    题目链接 题意就不多解释了,题目思路很简单,搜索就行了,但是暴搜会TLE,但是对于每一个dfs(X, Y),如果参数一样的话结果也是一样的,我们用一个二维数组去保存每次计算的位置的结果,最后从所有的解 ...

  4. 动态规划 POJ 1088 滑雪

    Description Michael 喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知 ...

  5. POJ 1088 滑雪 (动规)

    滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 75664 Accepted: 28044 Description Mich ...

  6. POJ - 1088 滑雪 【DP】【DFS】

    Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道 ...

  7. 【贪心】 POJ 1456 Supermarket 详解 (并查集/二叉堆优化)

    题目链接:POJ-1456 题目大意 有n件商品,每件商品的利润为,销售日期的截止时间为(即只能在时间前销售该物品).一天只能销售一件物品.问这n件商品的最大利润为多少 方案一 分析 有两种贪心策略, ...

  8. poj 1088滑雪

    经典的动态规划问题: 1 #include<iostream> 2 3 using namespace std; 4 5 int b[101][101]; 6 int d[101][101 ...

  9. Power Network POJ - 1459(EK算法模板+详解)

    题意: 总共有a个节点,其中有发电站b个.用户c个和调度器a-b-c个三种节点,每个发电站有一个最大发电量,每个用户有个最大接受电量,现在有d条有向边,边有一个最大的流量代表,最多可以流出这么多电,现 ...

最新文章

  1. 信息系统项目管理师:第9章:项目人力资源管理(2)-章节重点
  2. ASP.NET Core 登录登出 - ASP.NET Core 基础教程 - 简单教程,简单编程
  3. 索引存储模型-二分查找
  4. freebsd点到点的ipsec ***
  5. Android ToolBar 使用完全解析
  6. 线程join_Java 并发编程:线程间的协作(wait/notify/sleep/yield/join)
  7. 昨天刚招到一个程序员,第一天入职就离职了....因为不加班
  8. 分库分表学习总结(4)——分布式事务常见应用场景总结
  9. JAVA Timer 定时器
  10. bzoj2733 永无乡 splay树的启发式合并
  11. 周末献礼 MyVoix2.0.js 麦克风波形绘制(一)
  12. FR公式形态定义及运用范例
  13. python 高斯烟羽模型_高斯扩散模型-高斯烟羽大气污染扩散模型
  14. 最新hadoop大数据零基础入门高薪就业视频教程
  15. xampp的安装教程
  16. ShadowGun Demo学习(非技术向)
  17. tkinter运行时出现无响应问题
  18. 阿斯蒂芬萨法撒旦法撒旦发射点发射得分萨法撒旦法撒旦法
  19. 学人工智能看什么书?AI入门书籍推荐
  20. 千人规模互联网公司研发效能成功之路

热门文章

  1. Simple print, much secret
  2. 第十次作业是同一个人
  3. kaptcha验证码组件使用简介
  4. stand up meeting 1/14/2016
  5. Springmvc案例1----基于spring2.5的採用xml配置
  6. Andorid 实现图片转成pdf的方法
  7. 解决Http响应内容中文乱码问题
  8. CompletableFuture CompletableFuture.supplyAsync 异常处理
  9. setInterval和setTimeout的区别以及setInterval越来越快问题的解决方法
  10. nignx部署Vue单页面刷新路由404问题解决