POJ1088 滑雪 dp

来源:互联网 发布:java sop的理解 编辑:程序博客网 时间:2024/05/28 20:19

 题目

滑雪

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

 1  2  3  4 516 17 18 19 615 24 25 20 714 23 22 21 813 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 51 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9

Sample Output

25

DP,就是求最长降序子序列,有两种做法

一种比较容易的是循环dp 但是要从小到大,要对二维数组进行一个排序变成递增数组,感觉这里就有点坑。

另外的就是递归 从一个点开始, dp数组的数为他的路径数

遍历他周围的4个点,取其中路径数最大的点为他的dp的值。

代码如下

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define N 1001int dp[N][N],a[N][N],MAX;int r,c;int dir[4][2]={0,-1,-1,0,0,1,1,0};int  find(int i,int j){    int p;   int Max=0;   if(dp[i][j]!=0) return dp[i][j];   int s;   for(p=0;p<=3;p++)   {      int ar=i+dir[p][0];      int ac=j+dir[p][1];      if(ar<1||ac<1||ar>r||ac>c) continue;      if(a[ar][ac]>a[i][j])      {          s=find(ar,ac);          if(Max<s) Max=s;      }   }   dp[i][j]=Max+1;    return Max+1;}int main(){    MAX=0;    int n,i,j;    cin>>r>>c;    memset(dp,0,sizeof(dp));    for(i=1;i<=r;i++)     for(j=1;j<=c;j++)      cin>>a[i][j];    for(i=1;i<=r;i++)        for(j=1;j<=c;j++)        {            dp[i][j]=find(i,j);            if(MAX<dp[i][j]) MAX=dp[i][j];        }    cout<<MAX<<endl;    return 0;}


1 0
原创粉丝点击