1088 滑雪

经典dp,方程很容易写出

f[i,j]=max{f[i-1,j],f[i,j-1],f[i+1,j],f[i,j+1]}+1   //当集合中的点的高度大于当前点高度

即某点的状态由它的上下左右转移得到

但是矩阵的元素大小具有不确定性,无法直接通过循环自底向上计算f[i,j]

这里使用DFS的记忆化搜索,自顶向下按递归式计算,每求出一个点的值就保存起来,避免子问题重复计算

  1. //3445638_AC_47MS_348K
  2. #include<iostream>
  3. using namespace std;
  4. #define MAXN 102
  5. int move[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
  6. int f[MAXN][MAXN];
  7. int h[MAXN][MAXN];
  8. int r,c,i,j,ans;
  9. void dp(int x0,int y0)
  10. {
  11.     int x1,y1,i,m;
  12.     m=0;
  13.     for (i=0;i<4;++i)
  14.     {
  15.         x1=x0+move[i][0];
  16.         y1=y0+move[i][1];
  17.         if (h[x1][y1]>h[x0][y0])
  18.         {
  19.             if (f[x1][y1]==0)
  20.             {
  21.                 dp(x1,y1);
  22.             }
  23.             if (f[x1][y1]>m)
  24.             {
  25.                 m=f[x1][y1];
  26.             }
  27.         }
  28.     }
  29.     f[x0][y0]=m+1;
  30. }
  31. int main()
  32. {
  33.     //freopen("d:/in.txt","r",stdin);
  34.     while (cin>>r>>c)
  35.     {
  36.         memset(h,-1,sizeof(h));
  37.         memset(f,0,sizeof(f));
  38.         for (i=1;i<=r;++i)
  39.         {
  40.             for (j=1;j<=c;++j)
  41.             {
  42.                 cin>>h[i][j];
  43.             }
  44.         }
  45.         for (i=1;i<=r;++i)
  46.         {
  47.             for (j=1;j<=c;++j)
  48.             {
  49.                 if (f[i][j]==0)
  50.                 {
  51.                     dp(i,j);
  52.                 }
  53.             }
  54.         }
  55.         ans=0;
  56.         for (i=1;i<=r;++i)
  57.         {
  58.             for (j=1;j<=c;++j)
  59.             {
  60.                 if (f[i][j]>ans)
  61.                 {
  62.                     ans=f[i][j];
  63.                 }
  64.             }
  65.         }
  66.         cout<<ans<<endl;
  67.     }
  68.     return 0;
  69. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值