动态规划–数塔问题

今天学习了动态规划的数塔问题,老师给我们讲了三种方法。
(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)第三种方法没有用递归,从下往上考虑

  1. 一个底层为19、7、10、4、16的n层数塔问题就可以看成一个底层为21、28、19、21的n-1层数塔问题
  2. 而对于每一层只需要考虑自己下面连接的左右两边哪个数大,就用自身的值加上这个较大值来更新自身的值。
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;
} 

动态规划--数塔问题相关推荐

  1. 55 - 算法 -动态规划 -数塔问题 感觉都是数组建模 递推方法规则

    //模板#include <iostream> #include <cstdio> #include <string> using namespace std;/* ...

  2. c++ 动态规划(数塔)

    c++ 动态规划(dp) 题目描述 观察下面的数塔.写一个程序查找从最高点到底部任意位置结束的路径,使路径经过数字的和最大. 每一步可以从当前点走到左下角的点,也可以到达右下角的点. 输入 5 13 ...

  3. python 动态规划 数塔_数塔问题,简单的动态规划算法

    /* 数塔问题: 9 12 15 10 6 8 2 18 9 5 19 7 10 4 16 有形如图所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走, 一直走到底层,要求找出一条路径,使路径 ...

  4. 动态规划——数塔(hdu2084)

    首先介绍一下动态规划: 动态规划(dynamic programming),我们称之为DP,是求最优解的一种很常见的方法. 思想和背包基本一样,如对背包感兴趣的可以移步 http://blog.csd ...

  5. 动态规划——数塔问题

    从原点(顶层)出发,只能向左或者向右,找到一条路径使得路径上的数字和最大: #include<stdio.h> //#include"algorithm.h" #def ...

  6. 算法.动态规划 导航/数塔取数字问题

    目录 前言 从1+1开始 总结下概念 地图到图 回头看 代码 动态规划经典问题 前言 下面的概念和公式可能会吓到你,看不懂没关系,就是让你恶心的.反正我看着也挺恶心,专业就是让你看不懂,看懂了怎么能叫 ...

  7. C简单动态规划——爬数塔

    问题描述: 小明在某个角落发现了一座由数字组成的斜塔,他I想到塔顶去看看.小明可以从底层任意一个数字出发逐层爬上去,每次可以爬至上一层数字上或者上一层左边相邻的数字上(第1列只能爬至正上方上一层的数字 ...

  8. 算法学习(动态规划)- 数塔问题

    前言 之前碰到了扔鸡蛋问题(给你2个鸡蛋,在100层楼上扔,要求想出一个好的策略,去测出哪一层楼开始鸡蛋就会碎掉),一直摸不着头脑.后来才知道可以使用"动态规划"这种思想(或者叫算 ...

  9. 动态规划2(数塔问题)

    数塔问题是二维情况下动态规划的经典问题,下面以洛谷的一个例题来分析数塔问题以及动态规划:原题链接 题目描述 观察下面的数字金字塔.写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大 ...

最新文章

  1. NuGet学习笔记(3) 搭建属于自己的NuGet服务器
  2. memcache分布式 [一致性hash算法] 的php实现
  3. TensorFlow学习笔记(十一)读取自己的数据进行训练
  4. linux zk集群,linux ZooKeeper集群安装
  5. 记录一次查询log的经历
  6. yum安装最新的 LNMP
  7. 滑动平均_善杰告诉您初中物理学滑动变阻器的各种作用
  8. GitKraKenSetup工具——小章鱼
  9. 新起点、新目标--获得MVP后的感悟
  10. InstallShield 取消特定安装步骤
  11. qqxml卡片 php代码,qqxml卡
  12. 找不到方向?10大热门大数据应用领域总有一款适合你
  13. 【问题解决】seckill-秒杀项目 -- 服务端异常
  14. 极化码:基于单项式码的极化码部分序(Partial Order)表示
  15. ubuntu20.04 noetic 安装 Astra Pro 驱动
  16. 人对光波的三种特性_光的特点是什么?
  17. 社交数据在征信领域的应用探索
  18. 虚拟化操作系统ESXi 6.7安装配置--vSphere
  19. android百度地图行政区填充颜色
  20. rr与hr_BP、HR、RR、SPO2、ECG各是什么意思

热门文章

  1. Windows安全模式应用技巧介绍
  2. 图像元素遍历及像素值取反
  3. 《明朝那些事》爆笑妙语摘录
  4. 防cf上unordered_map被卡
  5. 判别式与生成式模型的区别
  6. Geomagic Touch(USB版本)在ROS下的配置和使用
  7. dcloud mui html5plus 5+sdk
  8. matlab的面积法,基于MATLAB的图像处理方法进行面积计算
  9. Windows打开远程桌面命令(打开RDP)
  10. jQuery取消绑定事件 单个事件 单个函数