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更长。事实上,这是最长的一条。
动态规划解题思路可详见另一篇文章。
#include
#include
#include
#define N 7
#define max(a,b) ((a>b)?a:b)
//定义四个方向,上、左、下、右
int dir[4][2] ={{-1,0},{0,-1},{1,0},{0,1}};
//保存最大长度
int maxRuslt = 0;
//定义矩阵
int a[N][N]={{INT_MAX,INT_MAX,INT_MAX,INT_MAX,INT_MAX,INT_MAX,INT_MAX},
{INT_MAX,1,2,3,4,5,INT_MAX},
{INT_MAX,16,17,18,19,6,INT_MAX},
{INT_MAX,15,24,25,20,7,INT_MAX},
{INT_MAX,14,23,22,21,8,INT_MAX},
{INT_MAX,13,12,11,10,9,INT_MAX},
{INT_MAX,INT_MAX,INT_MAX,INT_MAX,INT_MAX,INT_MAX,INT_MAX}};
//定义dp
int dp[N][N] = {0};
int dfs(int i,int j){
//递归出口
if((a[i][j] < a[i-1][j]) && (a[i][j] < a[i][j-1]) && (a[i][j] < a[i+1][j]) && (a[i][j] < a[i][j+1])){
return dp[i][j] = 1;
}
//已经算出来则不需再计算(备忘录)
else if(dp[i][j] > 0){
return dp[i][j];
}
else{
int k ;
int count = 0;
int temp = 0;
for(k=0 ; k < 4 ;k++){
if(a[i][j] > (a[i + dir[k][0]][j + dir[k][1]])){
//继续递归
temp = dfs(i + dir[k][0],j + dir[k][1]) + 1;
count = max(count,temp);
dp[i][j] = count;
//最大值保存在全局变量
maxRuslt = max(maxRuslt,count);
//printf("temp = %d;count = %d;maxResult = %d;\n",temp,count,maxRuslt);
}
}
return count;
}
}
int main()
{
int i,j;
for(i =1 ; i < N-1 ; i++){
for(j = 1 ; j < N-1 ; j++){
dfs(i,j);
}
}
printf("%d",maxRuslt);
return 0;
}