动态规划--数塔问题
动态规划–数塔问题
今天学习了动态规划的数塔问题,老师给我们讲了三种方法。
(1)第一种方法是原始的递归,就是从上往下看一个n层塔的最大路径问题可以转化为选出左右两个n-1层塔的最大路径问题的较大值,即:f(n)=max{ f(左,n-1), f(右,n-1) },依次向下直到第n层。
左边n-1数塔问题
右边n-1数塔问题
int f1(int i, int j){if(i < n-1) return data[i][j] + max(f1(i+1,j),f1(i+1,j+1));elsereturn data[i][j];
}
考虑到每次在计算是都会出现重复,因此有了方法二。
重复计算的区域
(2)第二种方法是对第一种方法的改进。把计算的结果放到一个数组里面就不会重复计算了。
int f2(int i,int j){if(i < n-1){if(d[i][j] == 0){d[i][j] = data[i][j] + max(f1(i+1,j),f1(i+1,j+1));}return d[i][j];}elsereturn data[i][j];}
(3)第三种方法没有用递归,从下往上考虑
- 一个底层为19、7、10、4、16的n层数塔问题就可以看成一个底层为21、28、19、21的n-1层数塔问题
- 而对于每一层只需要考虑自己下面连接的左右两边哪个数大,就用自身的值加上这个较大值来更新自身的值。
for(i = n-2;i>=0;i--){for(j = 0;j<=i;j++){data[i][j] = data[i][j] + max(data[i+1][j],data[i+1][j+1]);}}printf("路径上值最大为:%d",data[0][0]);
总结:1、相比之下我更喜欢第三种方法,因为它既不用写递归函数也没有重复计算,而且不需要用两个数组。而且第一种方法只能得到最大值,但是无法得到最大路径。
2、要得到最大路径,需要从上往下推。
printf("最优路径为:%d",data[0][0]);j = 0;for(i = 1;i<n;i++){if(d[i][j]>d[i][j+1]){printf("-> %d",data[i][j]);}else{printf("-> %d",data[i][j+1]);j = j + 1;} }
最优路径
全部代码:(记得在用一种方法的时候把其他两个注释掉)
#include<stdio.h>
const int n = 5;
int data[n][n] = {0};
int d[n][n] = {0};
int max(int x,int y){if(x>y) return x;else return y;
}
int f1(int i, int j){if(i < n-1) return data[i][j] + max(f1(i+1,j),f1(i+1,j+1));else return data[i][j];
}int f2(int i,int j){if(i < n-1){if(d[i][j] == 0){d[i][j] = data[i][j] + max(f1(i+1,j),f1(i+1,j+1));}return d[i][j];}else return data[i][j];}
int main(){int i,j;printf("请依次输入数塔各顶点的值:\n"); for(i = 0;i<n;i++){for(j = 0;j<=i;j++){scanf("%d",&data[i][j]);}}/方法一:从上到下,递归
// printf("路径上值最大为:%d",f1(0,0));/方法二:从上到下,加存储(备忘录法)
// printf("路径上值最大为:%d",f2(0,0));/方法三:从下到上,阶段划分(填表法) for(j = 0;j<n;j++){d[n-1][j] = data[n-1][j];}for(i = n-2;i>=0;i--){for(j = 0;j<=i;j++){d[i][j] = data[i][j] + max(d[i+1][j],d[i+1][j+1]);}}printf("路径上值最大为:%d\n",d[0][0]);//得出最优路径printf("最优路径为:%d",data[0][0]);j = 0;for(i = 1;i<n;i++){if(d[i][j]>d[i][j+1]){printf("-> %d",data[i][j]);}else{printf("-> %d",data[i][j+1]);j = j + 1;} }return 0;
}
动态规划--数塔问题相关推荐
- 55 - 算法 -动态规划 -数塔问题 感觉都是数组建模 递推方法规则
//模板#include <iostream> #include <cstdio> #include <string> using namespace std;/* ...
- c++ 动态规划(数塔)
c++ 动态规划(dp) 题目描述 观察下面的数塔.写一个程序查找从最高点到底部任意位置结束的路径,使路径经过数字的和最大. 每一步可以从当前点走到左下角的点,也可以到达右下角的点. 输入 5 13 ...
- python 动态规划 数塔_数塔问题,简单的动态规划算法
/* 数塔问题: 9 12 15 10 6 8 2 18 9 5 19 7 10 4 16 有形如图所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走, 一直走到底层,要求找出一条路径,使路径 ...
- 动态规划——数塔(hdu2084)
首先介绍一下动态规划: 动态规划(dynamic programming),我们称之为DP,是求最优解的一种很常见的方法. 思想和背包基本一样,如对背包感兴趣的可以移步 http://blog.csd ...
- 动态规划——数塔问题
从原点(顶层)出发,只能向左或者向右,找到一条路径使得路径上的数字和最大: #include<stdio.h> //#include"algorithm.h" #def ...
- 算法.动态规划 导航/数塔取数字问题
目录 前言 从1+1开始 总结下概念 地图到图 回头看 代码 动态规划经典问题 前言 下面的概念和公式可能会吓到你,看不懂没关系,就是让你恶心的.反正我看着也挺恶心,专业就是让你看不懂,看懂了怎么能叫 ...
- C简单动态规划——爬数塔
问题描述: 小明在某个角落发现了一座由数字组成的斜塔,他I想到塔顶去看看.小明可以从底层任意一个数字出发逐层爬上去,每次可以爬至上一层数字上或者上一层左边相邻的数字上(第1列只能爬至正上方上一层的数字 ...
- 算法学习(动态规划)- 数塔问题
前言 之前碰到了扔鸡蛋问题(给你2个鸡蛋,在100层楼上扔,要求想出一个好的策略,去测出哪一层楼开始鸡蛋就会碎掉),一直摸不着头脑.后来才知道可以使用"动态规划"这种思想(或者叫算 ...
- 动态规划2(数塔问题)
数塔问题是二维情况下动态规划的经典问题,下面以洛谷的一个例题来分析数塔问题以及动态规划:原题链接 题目描述 观察下面的数字金字塔.写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大 ...
最新文章
- NuGet学习笔记(3) 搭建属于自己的NuGet服务器
- memcache分布式 [一致性hash算法] 的php实现
- TensorFlow学习笔记(十一)读取自己的数据进行训练
- linux zk集群,linux ZooKeeper集群安装
- 记录一次查询log的经历
- yum安装最新的 LNMP
- 滑动平均_善杰告诉您初中物理学滑动变阻器的各种作用
- GitKraKenSetup工具——小章鱼
- 新起点、新目标--获得MVP后的感悟
- InstallShield 取消特定安装步骤
- qqxml卡片 php代码,qqxml卡
- 找不到方向?10大热门大数据应用领域总有一款适合你
- 【问题解决】seckill-秒杀项目 -- 服务端异常
- 极化码:基于单项式码的极化码部分序(Partial Order)表示
- ubuntu20.04 noetic 安装 Astra Pro 驱动
- 人对光波的三种特性_光的特点是什么?
- 社交数据在征信领域的应用探索
- 虚拟化操作系统ESXi 6.7安装配置--vSphere
- android百度地图行政区填充颜色
- rr与hr_BP、HR、RR、SPO2、ECG各是什么意思