滑雪
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 33 Accepted Submission(s) : 5
Problem Description
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更长。事实上,这是最长的一条。
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
Source
PKU
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main() 6 { 7 int x,y,i,j,num[105][105],a[10005],b[10005],k,c[10005],d[10005],sum[105][105],sign,tmp,MAX; 8 int ii,jj; 9 scanf("%d%d",&x,&y); 10 for(i=0,k=0;i<x;i++) 11 for(j=0;j<y;j++) 12 { 13 scanf("%d",&num[i][j]); 14 a[k]=i; 15 b[k]=j; 16 c[k]=num[i][j]; 17 d[k]=k; 18 k++; 19 } 20 for(i=k-1;i>=0;i--) 21 { 22 sign=i; 23 for(j=i-1;j>=0;j--) 24 if(c[sign]>c[j])sign=j; 25 if(sign!=i) 26 { 27 tmp=c[i]; 28 c[i]=c[sign]; 29 c[sign]=tmp; 30 31 tmp=d[i]; 32 d[i]=d[sign]; 33 d[sign]=tmp; 34 } 35 } 36 memset(sum,0,sizeof(sum)); 37 for(i=0;i<k;i++) 38 { 39 /* for(ii=0;ii<x;ii++) {for(jj=0;jj<y;jj++) printf("%d ",sum[ii][jj]);printf(" ");} 40 printf(" "); 41 */ 42 if((a[d[i]]<x)&&(num[a[d[i]]][b[d[i]]]>num[a[d[i]]+1][b[d[i]]])) 43 if(sum[a[d[i]]+1][b[d[i]]]<sum[a[d[i]]][b[d[i]]]+1) 44 sum[a[d[i]]+1][b[d[i]]]=sum[a[d[i]]][b[d[i]]]+1; 45 46 if((b[d[i]]<y)&&(num[a[d[i]]][b[d[i]]]>num[a[d[i]]][b[d[i]]+1])) 47 if(sum[a[d[i]]][b[d[i]]+1]<sum[a[d[i]]][b[d[i]]]+1) 48 sum[a[d[i]]][b[d[i]]+1]=sum[a[d[i]]][b[d[i]]]+1; 49 50 if((a[d[i]]>0)&&(num[a[d[i]]][b[d[i]]]>num[a[d[i]]-1][b[d[i]]])) 51 if(sum[a[d[i]]-1][b[d[i]]]<sum[a[d[i]]][b[d[i]]]+1) 52 sum[a[d[i]]-1][b[d[i]]]=sum[a[d[i]]][b[d[i]]]+1; 53 54 if((b[d[i]]>0)&&(num[a[d[i]]][b[d[i]]]>num[a[d[i]]][b[d[i]]-1])) 55 if(sum[a[d[i]]][b[d[i]]-1]<sum[a[d[i]]][b[d[i]]]+1) 56 sum[a[d[i]]][b[d[i]]-1]=sum[a[d[i]]][b[d[i]]]+1; 57 } 58 for(i=0,MAX=0;i<x;i++) 59 { 60 for(j=0;j<y;j++) 61 { 62 if(sum[i][j]>MAX) 63 MAX=sum[i][j]; 64 } 65 } 66 printf("%d ",MAX+1); 67 return 0; 68 }
(伪)修改2015.5.18
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 /*状态转移方程 合法的情况下:DP(i,j) = Max( DP(i,j-1), DP(i,j+1), DP(i-1,j), DP(i+1,j) ) + 1;*/ 5 int Map[110][110]; /*保存原始数据*/ 6 int D_P[110][110]; /*记录每一个点的最大滑雪长度*/ 7 int N ,M; 8 int DP(int i, int j) 9 { 10 int Max = 0; 11 if(Map[i][j]==-1) return 0; 12 if (D_P[i][j] > 0) return D_P[i][j]; 13 if (Map[i][j] > Map[i][j-1]) 14 { 15 if (Max < DP(i, j-1)) 16 { 17 Max = DP(i, j-1); 18 } 19 } 20 if (Map[i][j] > Map[i][j+1]) 21 { 22 if (Max < DP(i, j+1)) 23 { 24 Max = DP(i, j+1); 25 } 26 } 27 if (Map[i][j] > Map[i-1][j]) 28 { 29 if (Max < DP(i-1, j)) 30 { 31 Max = DP(i-1, j); 32 } 33 } 34 if (Map[i][j] > Map[i+1][j]) 35 { 36 if (Max < DP(i+1, j)) 37 { 38 Max = DP(i+1, j); 39 } 40 } 41 return D_P[i][j] = Max + 1; 42 } 43 44 int main() 45 { 46 47 int i, j,k; 48 while(scanf("%d%d",&N,&M)!=EOF) 49 { 50 int Max=0; 51 for (i=0; i<=N+1; i++)// 初始化数据 52 { 53 for (j=0; j<=M+1; j++) 54 { 55 if(i==0||j==0||i==N+1||j==M+1)Map[i][j]=-1; 56 else 57 { 58 scanf("%d",&Map[i][j]); 59 D_P[i][j] == 0; 60 } 61 } 62 } 63 for (i=1; i<=N; i++) 64 { 65 for (j=1; j<=M; j++) 66 { 67 k=DP(i,j); 68 if(Max<k)Max=k; 69 } 70 } 71 printf("%d ",Max); 72 } 73 return 0; 74 }