POJ 1088 滑雪

滑雪
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 65570   Accepted: 24041

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

一道比较简单的动态规划,dp[x][y]=max{周围四个点的步骤(如果该店高度比(x,y)低,否则设为0)}

[C++]
  1 #include<iostream>
  2 #include<cstring>
  3 
  4 using namespace std;
  5     
  6 int r,c;
  7 int h[101][101];
  8 long ans=0;
  9 long dp[101][101];
 10 
 11 long max(long a,long b,long c,long d)
 12 {
 13     long temp=a;
 14     if(b>temp)
 15         temp=b;
 16     if(c>temp)
 17         temp=c;
 18     if(d>temp)
 19         temp=d;
 20     return temp;
 21 }
 22 
 23 long dfs(int x,int y)
 24 {
 25     if(dp[x][y])
 26         return dp[x][y];
 27     if(x==1)
 28     {
 29         if(y==1)
 30             return dp[x][y]=max(0,h[x][y]>h[x+1][y]?dfs(x+1,y):0,0,h[x][y]>h[x][y+1]?dfs(x,y+1):0)+1;
 31         else if(y==c)
 32             return dp[x][y]=max(0,h[x][y]>h[x+1][y]?dfs(x+1,y):0,h[x][y]>h[x][y-1]?dfs(x,y-1):0,0)+1;
 33         else
 34             return dp[x][y]=max(0,h[x][y]>h[x+1][y]?dfs(x+1,y):0,h[x][y]>h[x][y-1]?dfs(x,y-1):0,h[x][y]>h[x][y+1]?dfs(x,y+1):0)+1;
 35     }
 36     else if(x==r)
 37     {
 38         if(y==1)
 39             return dp[x][y]=max(h[x][y]>h[x-1][y]?dfs(x-1,y):0,0,0,h[x][y]>h[x][y+1]?dfs(x,y+1):0)+1;
 40         else if(y==c)
 41             return dp[x][y]=max(h[x][y]>h[x-1][y]?dfs(x-1,y):0,0,h[x][y]>h[x][y-1]?dfs(x,y-1):0,0)+1;
 42         else
 43             return dp[x][y]=max(h[x][y]>h[x-1][y]?dfs(x-1,y):0,0,h[x][y]>h[x][y-1]?dfs(x,y-1):0,h[x][y]>h[x][y+1]?dfs(x,y+1):0)+1;
 44     }
 45     else if(y==1)
 46         return dp[x][y]=max(h[x][y]>h[x-1][y]?dfs(x-1,y):0,h[x][y]>h[x+1][y]?dfs(x+1,y):0,0,h[x][y]>h[x][y+1]?dfs(x,y+1):0)+1;
 47     else if(y==c)
 48         return dp[x][y]=max(h[x][y]>h[x-1][y]?dfs(x-1,y):0,h[x][y]>h[x+1][y]?dfs(x+1,y):0,h[x][y]>h[x][y-1]?dfs(x,y-1):0,0)+1;
 49     else
 50         return dp[x][y]=max(h[x][y]>h[x-1][y]?dfs(x-1,y):0,h[x][y]>h[x+1][y]?dfs(x+1,y):0,h[x][y]>h[x][y-1]?dfs(x,y-1):0,h[x][y]>h[x][y+1]?dfs(x,y+1):0)+1;
 51 }
 52 
 53 void initial_1()
 54 {
 55     memset(dp,0,sizeof(dp));
 56     if(h[1][1]<=h[1][2]&&h[1][1]<=h[2][1])
 57         dp[1][1]=1;
 58     if(h[1][c]<=h[1][c-1]&&h[1][c]<=h[2][c])
 59         dp[1][c]=1;
 60     if(h[r][1]<=h[r][2]&&h[r][1]<=h[r-1][1])
 61         dp[r][1]=1;
 62     if(h[r][c]<=h[r][c-1]&&h[r][c]<=h[r-1][c])
 63         dp[r][c]=1;
 64     for(int y=2;y<c;y++)
 65     {
 66         if(h[1][y]<=h[1][y-1]&&h[1][y]<=h[1][y+1]&&h[1][y]<=h[2][y])
 67             dp[1][y]=1;
 68         if(h[r][y]<=h[r][y-1]&&h[r][y]<=h[r][y+1]&&h[r][y]<=h[r-1][y])
 69             dp[r][y]=1;
 70     }
 71     for(int x=2;x<r;x++)
 72     {
 73         if(h[x][1]<=h[x-1][1]&&h[x][1]<=h[x+1][1]&&h[x][1]<=h[x][2])
 74             dp[x][1]=1;
 75         if(h[x][c]<=h[x-1][c]&&h[x][c]<=h[x+1][c]&&h[x][c]<=h[x][c-1])
 76             dp[x][c]=1;
 77     }
 78     for(int x=2;x<r;x++)
 79         for(int y=2;y<c;y++)
 80             if(h[x][y]<=h[x-1][y]&&h[x][y]<=h[x+1][y]&&h[x][y]<=h[x][y-1]&&h[x][y]<=h[x][y+1])
 81                 dp[x][y]=1;
 82 }
 83 
 84 void initial_2()
 85 {
 86     for(int x=1;x<=r;x++)
 87         for(int y=1;y<=c;y++)
 88             if(dp[x][y]!=1)
 89                 dp[x][y]=0;
 90 }
 91 
 92 void call(int x,int y)
 93 {
 94     long temp;
 95     initial_2();
 96     temp=dfs(x,y);
 97     if(temp>ans)
 98         ans=temp;
 99 }
100 
101 int main()
102 {
103     cin>>r>>c;
104 
105     for(int i=1;i<=r;i++)
106         for(int j=1;j<=c;j++)
107             cin>>h[i][j];
108     initial_1();
109     if(h[1][1]>=h[1][2]&&h[1][1]>=h[2][1])
110         call(1,1);
111     if(h[1][c]>=h[1][c-1]&&h[1][c]>=h[2][c])
112         call(1,c);
113     if(h[r][1]>=h[r][2]&&h[r][1]>=h[r-1][1])
114         call(r,1);
115     if(h[r][c]>=h[r][c-1]&&h[r][c]>=h[r-1][c])
116         call(r,c);
117     for(int y=2;y<c;y++)
118     {
119         if(h[1][y]>=h[1][y-1]&&h[1][y]>=h[1][y+1]&&h[1][y]>=h[2][y])
120             call(1,y);
121         if(h[r][y]>=h[r][y-1]&&h[r][y]>=h[r][y+1]&&h[r][y]>=h[r-1][y])
122             call(r,y);
123     }
124     for(int x=2;x<r;x++)
125     {
126         if(h[x][1]>=h[x-1][1]&&h[x][1]>=h[x+1][1]&&h[x][1]>=h[x][2])
127             call(x,1);
128         if(h[x][c]>=h[x-1][c]&&h[x][c]>=h[x+1][c]&&h[x][c]>=h[x][c-1])
129             call(x,c);
130     }
131     for(int x=2;x<r;x++)
132         for(int y=2;y<c;y++)
133             if(h[x][y]>=h[x-1][y]&&h[x][y]>=h[x+1][y]&&h[x][y]>=h[x][y-1]&&h[x][y]>=h[x][y+1])
134                 call(x,y);
135 
136     cout<<ans<<endl;
137 
138     return 0;
139 }

 

又参看了一下其他博客写的代码,发现自己洗的真的好长好长....

处理边缘问题时不需要像我写的那样,很麻烦地判断当前的点是定点,还是边缘的,还是内部的,只要在搜索它周围四个点时判断一下那四个点是不是在范围内即可~~

posted @ 2013-05-08 22:06  ~~Snail~~  阅读(439)  评论(2编辑  收藏  举报