数字三角形——递归、递推、记忆化搜索
2014-05-16 21:42
260 查看
数字三角形
描述:有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数。
问题:
从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来。如何走才能使得这个和尽量大?
分析:
不难看出此题是一个动态的决策问题:每次有两种选择——左下或右下。如果用回溯法求出所有的可能的路线,就可以从中选出最优的路线。但和往常一样,回溯法的效率太低:一个n层数字三角形的完整路线有2^n条,当n很大时回溯法的速度将让人无法忍受。因此本题讨论用递归,递推及记忆化搜索的方法实现,虽然还有其他的方法,但此时只讨论学习比较相似的这几种方法。
最先想到的是递归实现:
#include "stdio.h" #define maxn 100 int a[maxn][maxn],n; inline max(int x,int y) { return x>y?x:y; } //递归计算实现 int d(int x,int y) { return a[x][y]+(x==n?0:max(d(x+1,y),d(x+1,y+1))); } int main() { while(~scanf("%d",&n)) { int i,j; for(i=1;i<=n;i++){ for(j=1;j<=i;j++) scanf("%d",&a[i][j]); } printf("max:%d\n",d(1,1)); } return 0; }虽然这样做是正确的,但时间效率太低,其原因在于重复计算。
例: 在下列计算中d(3,2)被重复调用
d(2,1) 的计算会调用--> d(3,1) , d(3,2)
d(2,2) 的计算会调用--> d(3,2) , d(3,3)
递推的实现:
#include "stdio.h" #define maxn 100 int a[maxn][maxn],n; inline max(int x,int y) { return x>y?x:y; } //递推实现 int d(int x,int y) { int d ,i,j; for(j=1;j<=n;j++) d [j]=a [j]; for(i=n-1;i>=1;i--){ for(j=1;j<=i;j++) d[i][j]=a[i][j]+max(d[i+1][j],d[i+1][j+1]); } return d[x][y]; } int main() { while(~scanf("%d",&n)) { int i,j; for(i=1;i<=n;i++){ for(j=1;j<=i;j++) scanf("%d",&a[i][j]); } printf("max:%d\n",d(1,1)); } return 0; }
记忆化搜索实现:
#include "stdio.h" #include "string.h" #define maxn 100 int a[maxn][maxn],n; int d[maxn][maxn]; //记忆化搜索所使用的状态记忆数组 inline max(int x,int y) { return x>y?x:y; } /* 记忆话搜索。程序分成两部分。首先 memset(d,-1,sizeof(d)); 把d全部初始化为-1, 然后编写递归函数: */ int distance(int i,int j) { if(d[i][j]>=0) return d[i][j]; return d[i][j]=a[i][j]+(i==n?0:max(distance(i+1,j),distance(i+1,j+1))); } /* 上述程序依然是递归的,但同时也把计算结果保存在数组d中。题目中说各个数都是非负的,因此 如果已经计算过某个d[i][j],则它应是非负的,这样,只需把所有d初始化为-1,即可通过判断是否 d[i][j]>=0得知是否已经被计算过。 */ int main() { while(~scanf("%d",&n)) { int i,j; for(i=1;i<=n;i++){ for(j=1;j<=i;j++) scanf("%d",&a[i][j]); } memset(d,-1,sizeof(d)); //状态记忆化数组初始化 printf("max:%d\n",distance(1,1)); } return 0; }
相关文章推荐
- tyvj 1044 数字三角形 记忆化搜索
- 数字三角形问题,记忆化搜索
- 数字三角形递归与记忆化
- 数字三角形_递归_递推(动态规划)
- 普及练习场 递推与递归二分 数字三角形
- BSOJ 3022 又一类数字三角形--根据数据范围的优化+背包思想递推/搜索
- 递归,递推,记忆化搜索,空间优化(数字三角形)
- 动态规划 问题之数字三角形(正序递推)
- 动态规划(二)暴力递归的优化之路——数字三角形最大路径和
- hihoCoder 1037 : 数字三角形(记忆化)
- 【转】数字三角形-递推-动态规划
- 动态规划初步_数字三角形(递归,递推,数字化搜索)
- C++递归线性阵列搜索数字的方法
- 递推 数字三角形
- 一道题看懂递归、(深度搜索)dfs、记忆化搜索、动态规划(DP)的差别!
- 记忆化递归搜索(poj 1579)
- 【题&结论(递归标连通块)】【搜索(IDA*)】NKOJ 2440 数字消除游戏
- 动态规划问题数字三角形的(递归程序)
- 【递归】数字三角形 简单dp
- 三角形问题——(递归,递推,动态规划)