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

滑雪

总时间限制:       内存限制: 

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个整数,代表高度h0<=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); } 
         
       
      
      
     
     
    
    
   
   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值