动态规划(记忆化搜索)

http://poj.org/problem?id=1088

  1 // 典型的动态规划,用递归下的记忆化搜索来实现
  2 // 状态转移方程 合法的情况下:DP(i,j) = max( DP(i,j-1), DP(i,j+1), DP(i-1,j), DP(i+1,j) ) + 1;
  3 #include <iostream>
  4 using namespace std;
  5 
  6 int matrix[100][100];// 保存原始数据
  7 int cnt[100][100]; // 记录每一个点的最大滑雪长度
  8 int row ,col;
  9 
 10 int DP(int i, int j)
 11 {
 12     int max = 0;
 13 
 14     // 如果已经处理过,直接返回(记忆化搜索效率之所以高的原因:不重复计算)
 15     if (cnt[i][j] > 0) 
 16     {
 17         return cnt[i][j];
 18     }
 19 
 20     // 以下四块语句,只对合法的i和j,进行递归(递归的重点就是:剪去所有不合法的,只处理所有合法的!!!)
 21     if (j-1 >= 0)
 22     {
 23         if (matrix[i][j] > matrix[i][j-1])
 24         {
 25             if (max < DP(i, j-1))
 26             {
 27                 max = DP(i, j-1);
 28             }
 29         }
 30     }
 31 
 32     if (j+1 <= col-1)
 33     {
 34         if (matrix[i][j] > matrix[i][j+1])
 35         {
 36             if (max < DP(i, j+1))
 37             {
 38                 max = DP(i, j+1);
 39             }
 40         }
 41     }
 42 
 43     if (i-1 >= 0)
 44     {
 45         if (matrix[i][j] > matrix[i-1][j])
 46         {
 47             if (max < DP(i-1, j))
 48             {
 49                 max = DP(i-1, j);
 50             }
 51         }
 52     }
 53 
 54     
 55    
 56     // 注意,行数可能不等于列数!!!!
 57     if (i+1 <= row-1)
 58     {
 59         if (matrix[i][j] > matrix[i+1][j])
 60         {
 61             if (max < DP(i+1, j))
 62             {
 63                 max = DP(i+1, j);
 64             }
 65         }
 66     }
 67 
 68     // 将结果记录在cnt数组中(记忆化搜索的重点)
 69 
 70     // 如果左右上下都没有一个点的值比这个点的值大,则cnt[i][j] = max+1 = 1
 71     // 否则将左右上下各点最大滑雪长度记录在max中, 则cnt[i][j] = max+1 
 72     // 这就是max为什么要初始化为0的原因.
 73     return cnt[i][j] = max + 1;
 74 }
 75 
 76 
 77 int main()
 78 {
 79    
 80     int i, j; 
 81     cin>>row>>col;
 82 
 83     // 初始化数据
 84     for (i=0; i<=row-1; i++)
 85     {
 86         for (j=0; j<=col-1; j++)
 87         {
 88             cin>>matrix[i][j];
 89             cnt[i][j] == 0;
 90         }
 91     }
 92 
 93     // 处理每一个点,将其最大滑雪长度保存在cnt数组里面
 94     for (i=0; i<=row-1; i++)
 95     {
 96         for (j=0; j<=col-1; j++)
 97         {
 98             DP(i, j);
 99         }
100     }
101 
102 
103     // 遍历数组,求最大值
104     for (i=0; i<=row-1; i++)
105     {
106         for (j=0; j<=col-1; j++)
107         {
108             if (cnt[0][0] < cnt[i][j])
109             {
110                 cnt[0][0] = cnt[i][j];
111             }
112         }
113     }
114     
115     cout<<cnt[0][0]<<endl;
116 
117     return 0;
118 }
View Code

 

posted @ 2014-05-22 15:56  清风旋叶  阅读(506)  评论(0编辑  收藏  举报