pku1088題解

 

滑雪
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更長。事實上,這是最長的一條。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章