天天看点

acm pku 1088 滑雪

      这个题目相信大家都很熟悉,记得我在刚接触算法时就遇到过它,当时怎么也想不出来,现在找到了解决它的方法,确实挺高兴的。题目是这样的,给出你一个矩阵,矩阵中的数值代表着每一个滑点的高度。一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小,求可以滑动的最大长度。

     这是一个典型的动态规划的题目,具体的方法是先用一个二维数组来记录在每一个滑点可以滑向的最大长度,然后在这些长度中选出最长的那一个,而求在每一个滑点可以滑向的长度又是一个递归的过程。

源代码如下:

  1. #include <iostream>
  2. #include <queue>
  3. using namespace std;
  4. int R,C;
  5. int Mar[110][110];
  6. int D[110][110];
  7. int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
  8. int solve(int u,int v,int flag)
  9. {
  10.       if(u<0 || v<0 || u>=R || v>=C || Mar[u][v]>=flag) return 0;
  11.       if(D[u][v] != 0) return D[u][v];
  12.       int max = 1;
  13.       int x,y;
  14.       for(int i=0;i<4;++i)
  15.       {
  16.             int temp= 1;
  17.             x = u+dir[i][0];
  18.             y = v+dir[i][1];
  19.             temp+=solve(x,y,Mar[u][v]);
  20.             if(temp>max) max = temp;
  21.       }
  22.       D[u][v] = max;
  23.       return max;
  24. }
  25. int main()
  26. {
  27.       cin>>R>>C;
  28.       int max = 0,cas=0;
  29.       for(int i=0;i<R;++i)
  30.       {
  31.             for(int j=0;j<C;++j)
  32.             {
  33.                   scanf("%d",&Mar[i][j]);
  34.                   D[i][j] = 0;
  35.             }
  36.       }
  37.       for(int i=0;i<R;++i)
  38.       {
  39.             for(int j=0;j<C;++j)
  40.             {
  41.                     cas = solve(i,j,10001);
  42.                     //cout<<cas<<" ";
  43.                     if(cas > max) max = cas;
  44.             }
  45.             //cout<<endl;
  46.       }
  47.       cout<<max<<endl;
  48.       return 0;
  49. }

继续阅读