pku1088题解

来源:互联网 发布:java 审批流程框架 编辑:程序博客网 时间:2024/06/06 18:29
 

滑雪
Time Limit:1000MS  Memory Limit:65536K
Total Submit:11034 Accepted:3437

Description
Michael 喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个 区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子

 

Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。

Output
输出最长区域的长度。

Sample Input

 

Sample Output

 

 



这道题目非常的好,解题方法也很多,可以用DP,也可以用记忆化搜索,当然还可以暴力破解,不过常规的DP就
足以解决问题了,所以我用了常规的DP来解这道题目
动规方程可以写为path[x][y] = MAX{path[x-1][y], path[x+1][y], path[x][y+1], path[x][y-1]}
如果先按排序再递推的话复杂度会相对小一些

代码如下:


 #include<stdio.h>
#include<string.h>
#define MAX 100

struct point
{
int x,y,height;
}points[MAX*MAX];

int cmp(void const *a, void const *b)
{
return (*(struct point*)a).height - (*(struct point*)b).height;
}

int path[MAX][MAX];
int hills[MAX][MAX];
const int direction[4][2] = { {0,1},{0,-1},{1,0},{-1,0}};

int main()
{

int r, c, i, j, k, ans, x, y;
scanf("%d%d", &r, &c);
k = 0;
for (i = 0; i < r; ++i)
for (j = 0; j < c; ++j)
{
scanf("%d", &hills[i][j]);
points[k].x = i;
points[k].y = j;
points[k++].height = hills[i][j];
}

qsort(points, k, sizeof(struct point), cmp);
for (i = 0; i<r; i++)
for (j = 0; j <c;j++)
path[i][j] = 0;
ans = 0;
for (i=0;i<k;++i)
{
for (j=0;j<4;++j)
{
x=points[i].x+direction[j][0];
y=points[i].y+direction[j][1];
if (x>=0&&x<r&&y>=0&&y<c&&hills[x][y]<points[i].height&&path[points[i].x][points[i].y]<=path[x][y])
path[points[i].x][points[i].y]=path[x][y]+1;
}
if (ans<=path[points[i].x][points[i].y])
ans=path[points[i].x][points[i].y];

}
printf("%d/n",ans+1);
return 0;
}

25

5 5
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

 1  2  3  4 5

16 17 18 19 6

15 24 25 20 7

14 23 22 21 8

13 12 11 10 9

一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。