滑雪(dp+搜索)

来源:互联网 发布:模板引擎 node 编辑:程序博客网 时间:2024/06/08 02:59
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记忆一下;

代码如下:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <iostream>#include <algorithm>using namespace std;int dp[105][105];          //记录以每个点为起点所能走的最长距离;int mp[105][105];          //存每个点的高度;int next[4][2]={1,0,-1,0,0,1,0,-1};       //每个点都有四个方向可行;int R, C;                                //R:行, C:列;int dfs(int x, int y){                   //深度搜索;    if(dp[x][y]>0) return dp[x][y];      //如果(x,y)点已走过直接返回该点所能走的距离(步数);    int maxx, m;                                     maxx=1;                              //至少有一步;    for(int k=0; k<=3; k++){             //遍历四个方向,此时不需要标记,不会走重复的坐标;        int tx, ty;        tx=x+next[k][0];        ty=y+next[k][1];        if(tx>=R || ty>=C || tx<0 || ty<0) continue; //越界,就continue;        if(mp[tx][ty]<mp[x][y]){                    //下一坐标比该点小,就递归到下一坐标, 步数加1;            m=dfs(tx, ty)+1;            if(maxx<m) maxx=m;                          //记忆最大的步数;        }    }    dp[x][y]=maxx;                                   //储存最大的步数;    return maxx;}int main(){    scanf("%d%d",&R,&C);    for(int i=0; i<R; i++)        for(int j=0; j<C; j++)            scanf("%d",&mp[i][j]);    int maxx=0;    for(int i=0; i<R; i++)    for(int j=0; j<C; j++){        dp[i][j]=dfs(i, j);                         //每个点都dfs一遍, 找dp最大的;        if(maxx<dp[i][j]) maxx=dp[i][j];    }    printf("%d\n",maxx);    return 0;}


原创粉丝点击