动态规划-数字三角形

如图所示 从顶部出发 计算和最大的数字路径

我的思路:从底部开始,从左右两个数字中挑选最大的值与上一个数值相加

依次向上递推,最终求得最大值


存在的问题:存在重复计算 如底部的5和6 会被重复利用计算 浪费时间空间


动态规划思路:

创建一个与该数字三角矩阵规模一致的镜像矩阵 用来存储计算过的值 在下一次牵涉到重复计算时,直接取出计算即可

代码:

#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<time.h>
using namespace std;
#define MaxSize 101

int saveMaxSum[MaxSize][MaxSize];
int D[MaxSize][MaxSize];
int n = 0;   //行数

void main() {

	srand(time(NULL));

	cin >> n;    //表示三角形有多少行
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= i; ++j) {
			D[i][j] = rand() % 100;
			saveMaxSum[i][j] = -1;
		}

	//动态递推
	//先处理最后一行
	for (int k = 1; k <= n; ++k) {
		saveMaxSum[n][k] = D[n][k];  //先将最后一行赋值
	}

	
	for (int i = n-1; i >= 1; --i) {   //从倒数第二行开始计算
		for (int j = 1; j <= i; ++j) {
			saveMaxSum[i][j] = max(saveMaxSum[i + 1][j], saveMaxSum[i + 1][j + 1]) + D[i][j];  //将每一行的计算结果保留 用于下一次计算
		}
	}

	cout << saveMaxSum[1][1] << endl;

	system("PAUSE");
	return;
}


思路:将每一行的计算结果进行保留 在下一次计算时取出复用

这样就避免了重复计算


由这个例子看动态规划:

递归就是将原问题分解成多个子问题,然后进行逆推的过程

将原问题分解成若干个子问题 子问题和原问题形式类似或相同 子问题全部解决 原问题就解决了


该例子问题:第i行第j列 正下方到底边的最大值 和 右下方到底边的最大值

确定状态:数字所代表的行号和列号就是状态

三角形中 初始状态就是三角形底边数字 值就是底边数字的值


通过值已知的状态递推值未知的状态

转移方程:

已知值得状态(底层,起始点):

saveMaxSum[i][j] = D[i][j]

未知值的状态:

saveMaxSum[i][j] = max(saveMaxSum[i + 1][j], saveMaxSum[i + 1][j + 1]) + D[i][j];







  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值