动态规划之数字三角形
2017-03-30 11:00
274 查看
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径, 三角形的行数大于1小于等于100,数字为0-99. 输入: 5//行数 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 输出: 最大和 解题思路: 用二维数组存放数字三角形。 D(r,j):第r行第j个数字(r,j从1开始算) MaxSum(r,j):从D(r,j)到底边的各条路径中,最佳路径的数字之和。 问题:求MaxSum(1,1) 典型的递归问题。 D(r,j)出发,下一步只能走D(r+1,j)或者D(r+1,j+1).故对于N行的三角形: if(r==N) MaxSum(r,j)=D(r,j); else MaxSum(r,j)=Max{MaxSum(r+1,j),MaxSum(r+1,j+1)}+D(r,j);
代码如下:
#include<iostream> #include<algorithm> #define MAX 101 using namespace std; int D[MAX][MAX]; int n; int MaxSum(int i, int j) { if (i == n) 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 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; }
但是,上述的递归方法时间复杂度太大,为2的n次方,不可取。
因此,选择记忆递归型动归程序,其时间复杂度为n的2次方。
#include<iostream> #include<algorithm> #define MAX 101 using namespace std; int D[MAX][MAX]; int maxSum[MAX][MAX]; int n; 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); return max(x, y) + D[i][j]; } int main() { 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; } cout << MaxSum(1, 1) << endl; }
将动归程序转成递推程序:
#include<iostream> #include<algorithm> #define MAX 101 using namespace std; int D[MAX][MAX]; int maxSum[MAX][MAX]; int n; int main() { int i, j; cin >> n; for (i = 1; i <= n; i++) for (j = 1; j <= i; j++) cin >> D[i][j]; for (int i = 1; i <= n; ++i) maxSum [i] = D [i]; for (int i = n - 1; i >= 1; --i) for (int 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; }
进一步进行空间优化 没必要用二维maxSum数组存储每一个MaxSum(r,j),只要从底层一行行向上递推,那么只要一维数组maxSum[100]即可,即只要存储一行的MaxSum值就可以。 进一步考虑,连maxSum数组都可以不要,直接用D的第n行代替maxSum即可。节省空间,时间复杂度
#include<iostream> #include<algorithm> #define MAX 101 using namespace std; int D[MAX][MAX]; int * maxSum; int n; int main() { int i, j; cin >> n; for (i = 1; i <= n; i++) for (j = 1; j <= i; j++) cin >> D[i][j]; maxSum = D ; for (int i = n - 1; i >= 1; --i) for (int j = 1; j <= i; ++j) maxSum[j] = max(maxSum[j], maxSum[j + 1]) + D[i][j]; cout << maxSum[1] << endl; }
相关文章推荐
- The Triangle(数字三角形)动态规划
- 动态规划问题数字三角形的(递归程序)
- 动态规划 数字三角形
- 动态规划之数字三角形
- 动态规划 数字三角形 poj1163
- 动态规划_数字三角形问题
- 算法基础之python实现动态规划中数字三角形和最长上升子序列问题
- 069day(动态规划例题:数字三角形和输入输出流相关的类)
- 算法 -- 数字三角形之动态规划
- 动态规划0/1背包问题和数字三角形
- Problem A: 动态规划基础题目之数字三角形
- 动态规划(二)暴力递归的优化之路——数字三角形最大路径和
- 动态规划之数字三角形
- 动态规划——求数字三角形最优解和最优路径
- 简单动态规划---动态的数字三角形
- 动态规划--数字三角形问题
- 动态规划基础(数字三角形)
- 动态规划_数字三角形
- hihocoder#1037 : 数字三角形 经典简单动态规划
- 动态规划 问题之数字三角形(正序递推)