1. 程式人生 > >POJ 1088 滑雪(動態規劃)(解題報告)

POJ 1088 滑雪(動態規劃)(解題報告)

Description

Michael喜歡滑雪百這並不奇怪, 因為滑雪的確很刺激。可是為了獲得速度,滑的區域必須向下傾斜,而且當你滑到坡底,你不得不再次走上坡或者等待升降機來載你。Michael想知道載一個區域中最長底滑坡。區域由一個二維陣列給出。陣列的每個數字代表點的高度。下面是一個例子
 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更長。事實上,這是最長的一條。

Input

輸入的第一行表示區域的行數R和列數C(1 <= R,C <= 100)。下面是R行,每行有C個整數,代表高度h,0<=h<=10000。

Output

輸出最長區域的長度。

Sample Input

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

Sample Output

25
 這個題目的大高度受小的高度的影響,做一咱們可以動態規劃,詳見程式碼註釋:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
struct point
{
	int x;
	int y;
	int h;
};
 
int cmp(point a,point b)
{
	return a.h<b.h;
}
 
int main()
{
	int r,c;
	int i,j;
	int num=0;
	int height[101][101];
	int len[101][101];
	memset(len,0,sizeof(len));
	point points[10001];
	scanf("%d%d",&r,&c);
	for(i=0;i<r;i++)
	{
		for(j=0;j<c;j++)
		{
			scanf("%d",&height[i][j]);
			points[num].x=i;//記錄座標,下同 
			points[num].y=j;
			points[num].h=height[i][j];
			num++;
		}
	}
	sort(points,points+r*c,cmp);//按照高度從小到大的排 
	/*for(i=0;i<r*c;i++)
	{
		printf("%d ",points[i].h);
	}*/
	for(i=0;i<r*c;i++)//從小到大,動態規劃開始 
	{
		if(height[points[i].x][points[i].y]<height[points[i].x][points[i].y+1]&&len[points[i].x][points[i].y]>=len[points[i].x][points[i].y+1]&&points[i].y+1<c)
		{
			len[points[i].x][points[i].y+1]=len[points[i].x][points[i].y]+1;
		}
		if(height[points[i].x][points[i].y]<height[points[i].x+1][points[i].y]&&len[points[i].x][points[i].y]>=len[points[i].x+1][points[i].y]&&points[i].x+1<r)
		{
			len[points[i].x+1][points[i].y]=len[points[i].x][points[i].y]+1;
		}
		if(height[points[i].x][points[i].y]<height[points[i].x][points[i].y-1]&&len[points[i].x][points[i].y]>=len[points[i].x][points[i].y-1]&&points[i].y-1>=0)
		{
			len[points[i].x][points[i].y-1]=len[points[i].x][points[i].y]+1;
		}
		if(height[points[i].x][points[i].y]<height[points[i].x-1][points[i].y]&&len[points[i].x][points[i].y]>=len[points[i].x-1][points[i].y]&&points[i].x-1>=0)
		{
			len[points[i].x-1][points[i].y]=len[points[i].x][points[i].y]+1;
		}
	}
	int max=0;
	for(i=0;i<r;i++)
	{
		for(j=0;j<c;j++)
		{
			if(len[i][j]>max)
			{
				max=len[i][j];//找到最大的 
			}
		}
	}
	printf("%d\n",max+1);
	return 0;
}