P1434滑雪

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

思路

其实这道题可以直接dfs+记忆化完成,对于每一个位置,只有他四周的空格中有比它矮的才继续走
code:

#include
#include
#include
#include
#include
using namespace std;
int a[1005][1005],n,s,m,b[1005][1005],qq[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
int dfs(int x,int y)
{
 if (b[x][y]!=0)
 {
  return b[x][y];
 }
 s++;
 b[x][y]=1;
 for (int i=0;i<4;i++)
 {
  int dx=x+qq[i][0],dy=y+qq[i][1];
  if (dx<1||dx>n||dy<1||dy>m) continue;
  if (a[dx][dy]<a[x][y]) b[x][y]=max(dfs(dx,dy)+1,b[x][y]);
 }
 return b[x][y];
}
int main()
{
 scanf("%d%d",&n,&m);
 int mx=0;
 for (int i=1;i<=n;i++)
 {
  for (int j=1;j<=m;j++) scanf("%d",&a[i][j]);
 }
 for (int i=1;i<=n;i++)
 {
  for (int j=1;j<=m;j++)
  {
   mx=max(dfs(i,j),mx);
  }
 }
 cout<<mx;
 return 0;
}

当然我们也可以用动态规划完成,首先把每一个点从低到高排序,对于每一个点,如果它周围有比它小的点,那么求该点的最长路径,由于从低到高,所以可以证明每一个比该点低的点一定是最优的,满足最优子结构和无后效性。f[i][j]为第i,j个点的最长路径
f [ i ] [ j ] = m i n ( f [ i − 1 ] [ j ] , f [ i ] [ j − 1 ] , f [ i + 1 ] [ j ] , f [ i ] [ j + 1 ] ) ( 在 该 点 可 以 达 到 的 点 中 选 ) ( 1 < = i < = n , 1 < = j < = m ) f[i][j]=min(f[i-1][j],f[i][j-1],f[i+1][j],f[i][j+1])(在该点可以达到的点中选)(1<=i<=n,1<=j<=m) f[i][j]=min(f[i1][j],f[i][j1],f[i+1][j],f[i][j+1])()(1<=i<=n,1<=j<=m)
code:

#include
#include
#include
#include
#include
using namespace std;
int a[1005][1005],mx,c[1005][1005],n,m,qq[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
struct f{
 int x,y,z;
} b[1000009];
void dp(int x,int y)
{
 for (int i=0;i<4;i++)
 {
  int dx=x+qq[i][0],dy=y+qq[i][1];
  if (dx<1||dx>n||dy<1||dy>m) continue;
  if (a[dx][dy]<a[x][y]) c[x][y]=max(c[dx][dy]+1,c[x][y]);
 }
 return;
}
bool cmp(f a,f b)
{
 return a.z<b.z;
}
int main()
{
 scanf("%d%d",&n,&m);
 int mx=0;
 for (int i=1;i<=n;i++)
 {
  for (int j=1;j<=m;j++)
  {
   scanf("%d",&a[i][j]);
   b[i*m-m+j].x=i;
   b[i*m-m+j].y=j;
   b[i*m-m+j].z=a[i][j];
   c[i][j]=1;
  }
 }
 sort(b+1,b+1+n*m,cmp);
 for (int i=1;i<=n*m;i++)
 {
  dp(b[i].x,b[i].y);
  mx=max(mx,c[b[i].x][b[i].y]);
 }
 cout<<mx;
 return 0;
}

你可能感兴趣的:(dp,dfs)