百练 1088 滑雪

“人人为我”的解法:

dp[i][j]表示坐标为(i,j)的点开始下滑的最大长度。

则dp[i][j]为(i,j)周围四个点中比(i,j)低,且最大长度最大再加一的值

用结构体来储存一个点的坐标和高度,这样按高度从小到大排完序以后还不会丢失坐标的值

从小到大遍历所有的点,经过一个点(i,j)时,用递推公式求L(i,j)。

一个小技巧:

将矩阵height四周的值赋值为INF,你可以想想这是滑雪场四周非常非常高的围墙。

这样就避免了数组越界的判断,而且不会影响正确结果(因为我们找的是滑雪场内部的最大下滑长度)。

最后输出结果的时候,本来是直接输出最高点对应的长度,然后WA了

后来用循环找出最大值再输出就AC了

分析原因可能是这样的,可能有多个最高点,但并不是所有的最高点的下滑长度都是最大的

比如

1  2

2  2

这种情况下最大长度是2,可右下角的最高点对应的下滑长度却是1

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7
 8 struct POS
 9 {
10     int h;
11     int x, y;
12 }pos[10000 + 10];
13
14 bool cmp(POS a, POS b)
15 {
16     return (a.h < b.h);
17 }
18
19 const int INF = 100000;
20 int height[110][110];
21 int dp[110][110];
22
23 int main(void)
24 {
25     #ifdef LOCAL
26         freopen("1088in.txt", "r", stdin);
27     #endif
28
29     int r, c;
30     int i, j;
31     scanf("%d%d", &r, &c);
32     int tot = r * c;
33     int cnt = 0;
34     for(i = 1; i <= r; ++i)
35         for(j = 1; j <= c; ++j)
36         {
37             scanf("%d", &height[i][j]);
38             pos[++cnt].h = height[i][j];
39             pos[cnt].x = j;
40             pos[cnt].y = i;
41             dp[i][j] = 1;
42         }
43     for(i = 0; i <= c; ++i)
44     {
45         height[0][i] = height[r+1][i] = INF;
46         dp[0][i] = dp[r+1][i] = 1;
47     }
48     for(i = 0; i <= r; ++i)
49     {
50         height[i][0] = height[i][c+1] = INF;
51         dp[i][0] = dp[i][c+1] = 1;
52     }
53     sort(pos+1, pos+tot+1, cmp);
54     for(i = 2; i <= tot; ++i)
55     {
56         int x = pos[i].x;
57         int y = pos[i].y;
58         if(height[y-1][x]<pos[i].h)
59             dp[y][x] = max(dp[y][x], dp[y-1][x]+1);
60         if(height[y+1][x]<pos[i].h)
61             dp[y][x] = max(dp[y][x], dp[y+1][x]+1);
62         if(height[y][x-1]<pos[i].h)
63             dp[y][x] = max(dp[y][x], dp[y][x-1]+1);
64         if(height[y][x+1]<pos[i].h)
65             dp[y][x] = max(dp[y][x], dp[y][x+1]+1);
66     }
67
68     int ans = 1;
69     for(i = 1; i <= r; ++i)
70         for(j = 1; j <= c; ++j)
71             ans = max(ans, dp[i][j]);
72     printf("%d\n", ans);
73     return 0;
74 }

代码君

百练 1088 滑雪

时间: 2024-10-27 07:10:51

百练 1088 滑雪的相关文章

百练1088:滑雪 【DP】+【DFS】

总Time Limit: 1000ms Memory Limit: 65536kB Description Michael喜欢滑雪百这并不奇怪, 由于滑雪的确非常刺激.但是为了获得速度,滑的区域必须向下倾斜,并且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长的滑坡.区域由一个二维数组给出.数组的每一个数字代表点的高度.以下是一个 样例 1  2  3  4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 1

POJ 1088 滑雪 (动规)

滑雪 Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 75664 Accepted: 28044 Description Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑坡.区域由一个二维数组给出.数组的每个数字代表点的高度.下面是一个例子 1 2 3 4 5 16 17 18 1

[OpenJudge] 百练2754 八皇后

八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. 对于某个满足要求的8皇后的摆放方法,定义一个皇后串a与之对应,即a=b1b2...b8,其中bi为相应摆法中第i行皇后所处的列数.已经知道8皇后问题一共有92组解(即92个不同的皇后串).给出一个数b,要求输出第b个串.串的比较是这样的:皇后串x置于皇后串y之前,当且仅当将x视为整数时比y小. I

poj 百练 2765 八进制小数(精度问题)

2765:八进制小数 查看 提交 统计 提示 提问 总时间限制:  1000ms  内存限制:  65536kB 描述 八进制小数可以用十进制小数精确的表示.比如,八进制里面的0.75等于十进制里面的0.963125 (7/8 + 5/64).所有小数点后位数为n的八进制小数都可以表示成小数点后位数不多于3n的十进制小数. 你的任务是写一个程序,把(0, 1)中的八进制小数转化成十进制小数. 输入 输入包括若干八进制小数,每个小数占用一行.每个小数的形式是0.d1d2d3 ... dk,这里di

hdu 1088 滑雪

果然书要结合题来看才有效果 通过这题对记忆化搜索有了初步的理解 碰到没有访问过的点 进行搜索 之后记录下该点能滑出的最远距离 碰到搜索过的点 直接加上 dp[i] 就可以了 #include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<stack> #

POJ 1088 滑雪 记忆化优化题解

本题有人写是DP,不过和DP还是有点差别的,应该主要是记忆化 Momoization 算法. 思路就是递归,然后在递归的过程把计算的结果记录起来,以便后面使用. 很经典的搜索题目,这种方法很多题目考到的. 关键还是如何把代码写清晰工整了,O(∩_∩)O~. #include <stdio.h> const int MAX_N = 101; int R, C; int arr[MAX_N][MAX_N]; int tbl[MAX_N][MAX_N]; inline int max(int a,

poj 1088 滑雪

http://poj.org/problem?id=1088 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 int g[200][200]; 7 int dp[200][200]; 8 int r,c; 9 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; 10 int max1=-1; 11 12

[ACM] poj 1088 滑雪 (记忆化搜索DFS)

求n*m网格内矩形的数目[ACM] poj 1088 滑雪 (记忆化搜索DFS),布布扣,bubuko.com

ACM/ICPC 之 递归(POJ2663-完全覆盖+POJ1057(百练2775)-旧式文件结构图)

POJ2663-完全覆盖 题解见首注释 //简单递推-三个米诺牌(3*2)为一个单位打草稿得出规律 //题意-3*n块方格能被1*2的米诺牌以多少种情况完全覆盖 //Memory 132K Time: 0 Ms #include<iostream> #include<cstring> #include<cstdio> using namespace std; int ans; //开始平铺 int Tiling(int n) { int sum = 0; if (n =