滑雪
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 86878 | Accepted: 32506 |
Description
Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激。可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你。Michael想知道载一个区域中最长底滑坡。区域由一个二维数组给出。数组的每个数字代表点的高度。下面是一个例子
一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小。在上面的例子中,一条可滑行的滑坡为24-17-16-1。当然25-24-23-...-3-2-1更长。事实上,这是最长的一条。
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更长。事实上,这是最长的一条。
Input
输入的第一行表示区域的行数R和列数C(1 <= R,C <= 100)。下面是R行,每行有C个整数,代表高度h,0<=h<=10000。
Output
输出最长区域的长度。
Sample Input
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
Sample Output
25
解题思路:
典型的动态规划,记忆化搜索来实现
状态转移方程式 :DP(i,j) = max( DP(i,j-1), DP(i,j+1), DP(i-1,j), DP(i+1,j) ) + 1;
注意边界。
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 #define N 105 5 int cnt[N][N],mp[N][N],r,c;//mp输入,cnt出结果 6 int DP(int i,int j) 7 { 8 if(cnt[i][j]>0) return cnt[i][j];//已经搜过的直接返回 9 int max=0; 10 if(j>1 && mp[i][j]>mp[i][j-1] && max<DP(i,j-1))//注意是否合法 11 { 12 max=DP(i,j-1); 13 } 14 if(i>1 && mp[i][j]>mp[i-1][j] && max<DP(i-1,j)) 15 { 16 max=DP(i-1,j); 17 } 18 if(j<c && mp[i][j]>mp[i][j+1] && max<DP(i,j+1)) 19 { 20 max=DP(i,j+1); 21 } 22 if(i<r && mp[i][j]>mp[i+1][j] && max<DP(i+1,j)) 23 { 24 max=DP(i+1,j); 25 } 26 return cnt[i][j]=max+1; 27 } 28 int main() 29 { 30 while(~scanf("%d%d",&r,&c)) 31 { 32 memset(mp,0,sizeof(mp)); 33 memset(cnt,0,sizeof(cnt)); 34 for(int i=1;i<=r;i++) 35 for(int j=1;j<=c;j++) 36 scanf("%d",&mp[i][j]); 37 38 for(int i=1;i<=r;i++) 39 for(int j=1;j<=c;j++) 40 DP(i,j); 41 42 int ans=0; 43 for(int i=1;i<=r;i++) 44 for(int j=1;j<=c;j++) 45 if(cnt[i][j]>ans) ans=cnt[i][j]; 46 printf("%d ",ans); 47 } return 0; 48 }