动态规划之数字三角形
2017-11-19 14:29
295 查看
读北京大学李文新老师的《算法基础与在线实践》觉得动态规划这篇老师写的很好,就写了这篇博客,算是记笔记吧!
数字三角形问题:
如:
1
3 2
4 10 1
4 3 2 20
寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大,
路径上的每一步只能往左下或者右下走。
输入格式:
1
3 2
4 10 1
4 3 2 20
分析:我们可以用一个二维数组来存储这个数字三角形。D(i,j)表示第i行j列。i,j从1开始算。MaxSum(i, j)表示从D(i,j)到底边的各条路径中,最佳路径的数字之和。则问题就变成了求MaxSum(1,1)。
1.递归法:
不过这种做法需要不停的递归调用函数,而且会重复计算已经计算过的结果。对运行时间提出了极大的要求,很显然这不是很好的算法。
2.记忆型递归! 为了解决重复计算问题,我们将已经计算过的值用一个二维数组存储起来,当我们计算某结点时,先判断这个值是否已经计算过,如果计算过,则直接将这个值返回即可!当然这个二维数组要与我们用于存储的三角形数字的那个二维数组同等大小。
3.动态规划的思想!由于以上两种情况皆使用了递归,在计算机中调用函数是很耗内存的,所以我们使用一种不调用函数的方法,递推法!
数字三角形问题:
如:
1
3 2
4 10 1
4 3 2 20
寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大,
路径上的每一步只能往左下或者右下走。
输入格式:
1
3 2
4 10 1
4 3 2 20
分析:我们可以用一个二维数组来存储这个数字三角形。D(i,j)表示第i行j列。i,j从1开始算。MaxSum(i, j)表示从D(i,j)到底边的各条路径中,最佳路径的数字之和。则问题就变成了求MaxSum(1,1)。
1.递归法:
#include <iostream> #include <algorithm> #define Max 101 using namespace std; int D[Max][Max]; //定义矩阵大小 int n; //行数 int MaxSum(int i,int j){ //递归求某个子问题 if(n==i){ return D[i][j]; } int x=MaxSum(i+1,j);//左下 int y=MaxSum(i+1,j+1);//右下 return max(x,y)+D[i][j]; } int main(int argc, char** argv) { int i,j; cin>>n; for(i=1;i<=n;i++){ for(j=1;j<=i;j++){ cin>>D[i][j]; } } cout<<MaxSum(1,1)<<endl; return 0; }
不过这种做法需要不停的递归调用函数,而且会重复计算已经计算过的结果。对运行时间提出了极大的要求,很显然这不是很好的算法。
2.记忆型递归! 为了解决重复计算问题,我们将已经计算过的值用一个二维数组存储起来,当我们计算某结点时,先判断这个值是否已经计算过,如果计算过,则直接将这个值返回即可!当然这个二维数组要与我们用于存储的三角形数字的那个二维数组同等大小。
#include <iostream> #include <algorithm> #define Max 101 using namespace std; int n;//行数 int D[Max][Max];//定义矩阵大小 int maxSum[Max][Max];//用于存储计算过的结果 int MaxSum(int i,int j){ if(maxSum[i][j]!=-1)//已经计算过 return maxSum[i][j]; if(i==n) return D[i][j]; int x=MaxSum(i+1,j); int y=MaxSum(i+1,j+1); maxSum[i][j]=max(x,y)+D[i][j]; return maxSum[i][j]; } int main(int argc, char** argv){ int i,j; cin>>n; for(i=1;i<=n;i++){ for(j=1;j<=i;j++){ cin>>D[i][j]; maxSum[i][j]=-1;//没有计算过的标志为-1 } } cout<<MaxSum(1,1)<<endl; return 0; }
3.动态规划的思想!由于以上两种情况皆使用了递归,在计算机中调用函数是很耗内存的,所以我们使用一种不调用函数的方法,递推法!
#include <iostream> #include <algorithm> #define Max 101 using namespace std; int D[Max][Max];//定义矩阵大小 int n;//行数 int maxSum[Max][Max];////用于存储计算过的结果 int main(int argc, char** argv){ int i,j; cin>>n; for(i=1;i<=n;i++){ for(j=1;j<=i;j++){ cin>>D[i][j]; } } for(i=1;i<=n;i++)//将最后一行赋值到maxSum [i] i=1~n maxSum [i]=D [i]; for(i=n-1;i>=1;i--){//递推求maxSum[i][j] for(j=1;j<=i;j++){ maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j];//自底向上递推 } } cout<<maxSum[1][1]<<endl; return 0; }
相关文章推荐
- 简单动态规划---动态的数字三角形
- 算法:动态规划-数字三角形的最优解(打印路径)
- The Triangle(数字三角形)动态规划
- 动态规划--数字三角形
- 动态规划之数字三角形
- 算法 -- 数字三角形之动态规划
- YTU.3134: 动态规划基础题目之数字三角形
- 动态规划--(数字三角形 poj1163)
- 算法基础之python实现动态规划中数字三角形和最长上升子序列问题
- 动态规划入门-数字三角形
- 经典动态规划问题--数字三角形 POJ--1163
- 动态规划问题数字三角形的(递归程序)
- 动态规划 问题之数字三角形(正序递推)
- 069day(动态规划例题:数字三角形和输入输出流相关的类)
- 动态规划--数字三角形
- 动态规划0/1背包问题和数字三角形
- 动态规划(二)暴力递归的优化之路——数字三角形最大路径和
- 动态规划——求数字三角形最优解和最优路径
- OJ-3134 动态规划基础题目之数字三角形
- 动态规划入门-POJ 1163-The Triangle(数字三角形)