POJ-1088-滑雪-解题报告-动态规划-记忆化搜索

在给出这道题的解题报告之前,先看下记忆化搜索的个人理解。
以最简单的递归求阶乘的函数进行说明。
常见的求阶乘的代码是这样的:

int fac(int n) { if(n == 1) return 1; else return n * fac(n - 1); }

为了实现不重复递归调用,使用一个全局数组对已求得的结果进行保存;另外,每次返回结果前,都对全局数组进行相应赋值。
以下是实现代码:

#include <iostream> using namespace std; const int MAX = 20; /*全局数组。用来保存阶乘的结果。 *由于是全局数据,故不显式初始化的情况下, *所有数组元素元均被置为0。 */ __int64 valArr[MAX + 1]; /*求阶乘函数。*/ __int64 fac(int n) { /*对已求得n!的情况下,则直接返回。避免了重复递归调用。*/ if(valArr[n] > 0) return valArr[n]; /*以下代码跟平常求阶乘的代码很相似,只是多了对valArr数组赋值的语句。*/ if(n == 1) { valArr[n] = 1; return valArr[n]; } valArr[n] = n * fac(n - 1); return valArr[n]; } int main() { /*若只是求fac(MAX),则效率没有明显差异。 *但在循环过程中,实际上fac(MAX)会调用fac(MAX-1)的结果, *fac(MAX-1)会调用fac(MAX-2)的结果……故将已求得的结果保存起来, *效率就会得到提升。 */ for(int i = 1; i <= MAX; i++) cout << fac(i) << endl; return 0; }

最后是POJ-1088题的代码:

#include <iostream> using namespace std; const int MAX_SIZE = 100; int r, c; int arr[MAX_SIZE][MAX_SIZE]; //保存滑雪区域信息的全局数组。 int count[MAX_SIZE][MAX_SIZE]; //保存每个点最长滑雪长度信息的全局数组。 /*求点(i, j)最长滑雪长度的函数*/ int height(int i, int j) { /*若已求得结果,则直接返回。*/ if(count[i][j] > 0) return count[i][j]; /*保存(i, j)点的上下左右点的最大滑雪长度*/ int maxHeight = 0; /*由于要使用arr[i - 1][j],故先对i-1的合法性进判断*/ if(i - 1 >= 0) { /*只有(i-1, j)点的高度值小于(i, j)的点的高度值才进行计算*/ if(arr[i - 1][j] < arr[i][j]) { /*递归调用height函数,由于每求得一点的结果均进行了保存,故不会无限递归调用。 *广度搜索。 */ int h1 = height(i - 1, j); if(maxHeight < h1) maxHeight = h1; } } /*以下三段代码类似*/ if(i + 1 <= r - 1) { if(arr[i + 1][j] < arr[i][j]) { int h2 = height(i + 1, j); if(maxHeight < h2) maxHeight = h2; } } if(j - 1 >= 0) { if(arr[i][j - 1] < arr[i][j]) { int h3 = height(i, j - 1); if(maxHeight < h3) maxHeight = h3; } } if(j + 1 <= c - 1) { if(arr[i][j + 1] < arr[i][j]) { int h4 = height(i, j + 1); if(maxHeight < h4) maxHeight = h4; } } /*对count全局数组进行赋值。 *由于maxHeight>=0,故被赋值后的count[i][j]>=1。 */ count[i][j] = maxHeight + 1; /*最后还返回(i, j)点的最大滑雪长度*/ return count[i][j]; } int main() { cin >> r >> c; /*初始化保存滑雪区域信息的数组*/ for(int i = 0; i < r; i++) { for(int j = 0; j < c; j++) { cin >> arr[i][j]; } } int maxHeight = 0; int h; /*求得最长的“最长滑雪长度”*/ for(int i = 0; i < r; i++) { for(int j = 0; j < c; j++) { h = height(i, j); if(h > maxHeight) maxHeight = h; } } cout << maxHeight << endl; return 0; }

你可能感兴趣的:(c)