您的位置:首页 > 编程语言 > C语言/C++

【动态规划·经典例题】滑雪

2016-12-31 10:08 120 查看

滑雪

总时间限制:       内存限制: 
1000ms              65536kB
描述
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更长。事实上,这是最长的一条。
输入
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
输出
输出最长区域的长度。
样例输入

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

样例输出

25

分析

每个人可以从某个点滑向周围四个点的其中一点,先要对高度进行从小到大排序,然后比较找出最长的一条路线。或者用记忆化搜索,无需排序,按照行的顺序,利用递归逐点求出区域中到此点的最长路径,每个点的最长路径只求一次。
 

#include
#include
#include
using namespace std;
int dx[5]={0,-1,0,1,0}, //x的坐标增量
dy[5]={0,0,1,0,-1}; //y的坐标增量
long r,c,i,j,p,t,ans;
long m[101][101],f[101][101];
int search(int,int);
int  main(){
//freopen("f://102.txt","r",stdin);
cin>>r>>c;
ans=0;
for(i=1;i<=r;i++)
for(j=1;j<=c;j++)
cin>>m[i][j];    //读入每个点的高度
for(i=1;i<=r;i++)  //按照行的顺序,利用递归逐点求出区域中达到此点的最长路径
for(j=1;j<=c;j++){
t=search(i,j);
f[i][j]=t;
if(t>ans) ans=t; //寻找最大长度值
}
cout<0){//此点长度已经求出,不必进行进一步递归,保证每一个点的最大长度只求一次,这是记忆化搜索到特点
return (f[x][y]);
}
t=1;
for(i=1;i<=4;i++){  //从四个方向上搜索能达到的[x,y]的点
nx=x+dx[i];  //加上横、纵坐标
ny=y+dy[i];
if((nx>=1)&&(nx<=r)&&(ny>=1)&&(ny<=c)&&(m[x][y]t) t=tmp;
}
}
f[x][y]=t;
return (t);
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息