C++数字三角形问题(动态规划)
一、问题描述
★问题描述:给字一个由n行数字组成的数字三角形(等腰三角形)。试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大。
★算法设计:对于给定的由n行数字组成的数字三角形,计算从三角形的项至底的路径经过的数字和的最大值。
★数据输入:由文件input.txt提供输入数据。文件的第1行是数字三角形的计数n,1≤n≤100。接下来n行是数字三角形各行中的数字。所有数字在0~99之间。
★结果输出:将计算结果输出到文件output.txt。文件第1行中的数是计算出的最大值。
输入文件示例:input.txt
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出文件示例:output.txt
30
二、问题分析
(1).输入数据的储存和表示:
先将数字三角形由一个等腰变形为一个直角三角形,便于我们使用矩阵来保存和表示。
矩阵表示如下:
0 0 0 0 0 0
0 7 0 0 0 0
0 3 8 0 0 0
0 8 1 0 0 0
0 2 7 4 4 0
0 4 5 2 6 5
相应输入部分的代码:
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
cinfile>>NT[i][j];
}
for(int j=i+1;j<=n;j++){
NT[i][j]=0;
}
}
(2).解题思路
基本思路--采用自顶向下的方法
A.思路一:自顶向下依次遍历,在碰到分叉路的时候选择较大的数。(错误--局部最优并不等于整体最优)
比如上述例题按这种方法得到的“最优解”:7+8+1+7+5=27
而实际上的最优解:7+3+8+7+5=30
B.思路二:自顶向下依次遍历,列举出所有路径的大小,最后再进行比较。(正确)
保存数据:首先,我们需要一个矩阵储存当前路径的大小,这里我们使用NT(number triangle)保存原来的数字三角形,使用ST(sum triangle)保存当前路径的大小。由于每个路径数据再往下发展的时候都有两种可能,因此这个矩阵的大小为n*2(n-1),这里的话我直接使用了2n。
算法设计:
初始化,ST[i][0]=0;ST[0][j]=0;ST[1][1]=NT[1][1]
自顶向下遍历
当前路径的和=上一层路径的和+当前数据;
r[1][1]=a[1][1];
for(int i=2;i<=n;i++){
int count=1;
for(int j=1;j<=i-1;j++){
r[i][count++]=r[i-1][j]+a[i][j];//每一个数据对应两条路径
r[i][count++]=r[i-1][j]+a[i][j+1];
}
}
遍历结束后,ST的数据存储情况
比如10就是路径:7+3的和;
15就是路径:7+8的和;
等等
回溯最优路径:
由于我们在计算最优路径时,用ST保存了所有当前路径的大小。因此我们只需要用最后的最优路径的数值依次往回减就可以求出最优路径了。由于我们的回溯是自底向上,路径的数据顺序是倒着的。因此这里使用了栈来储存路径数据,利用其后进先出的特点回溯出最优路径。
三、详细设计(从算法到程序)
#include<iostream>
#include<stack>
#include<fstream>
#include<sstream>
using namespace std;
//计算数字三角形最大路径的值
int Numtri(int n,int **a,int **r){r[1][1]=a[1][1];for(int i=2;i<=n;i++){int count=1;for(int j=1;j<=i-1;j++){r[i][count++]=r[i-1][j]+a[i][j];r[i][count++]=r[i-1][j]+a[i][j+1];}}
}
//回溯最优路径
int Traceback(int n,int posi,int **r,ofstream &outfile){stack<int>trace; //建立一个堆栈,利用其后进先出的特点来打印出路径int j=posi/2+1,c=r[n][posi];for(int i=n-1;i>=0;i--){//从最后一层开始往上回溯trace.push(c-r[i][j]);c=r[i][j];if(j%2==0) j=j/2; else j=j/2+1;}while(!trace.empty()){outfile<<trace.top()<<" ";trace.pop();}
}int main(){ifstream cinfile;cinfile.open("input.txt",ios::in);int n;cinfile>>n;int **NT=new int *[n+1]();int **ST=new int *[n+1]();for(int i=0;i<=n;i++){NT[i]=new int[n+1];ST[i]=new int[2*(n+1)];}for(int i=0;i<=n;i++){NT[0][i]=0;NT[i][0]=0;}for(int i=1;i<=n;i++){for(int j=1;j<=i;j++){cinfile>>NT[i][j];}for(int j=i+1;j<=n;j++){NT[i][j]=0;}}for(int i=0;i<=n;i++)for(int j=0;j<=2*n;j++) ST[i][j]=0; cinfile.close();ofstream outfile;outfile.open("output.txt",ios::out);Numtri(n,NT,ST);int Max=ST[n][1],pos=1;for(int i=2;i<=2*n;i++){if(Max<ST[n][i]){Max=ST[n][i];pos=i;}}outfile<<Max<<endl;Traceback(n,pos,ST,outfile);return 0;
}
/*
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
*/
四、程序运行结果
五、分析与总结
在做动态规划这一类问题时一定要注意很多时候局部最优解并不等于整体最优解。
C++数字三角形问题(动态规划)相关推荐
- python--lintcode109.数字三角形(动态规划)
描述 给定一个数字三角形,找到从顶部到底部的最小路径和.每一步可以移动到下面一行的相邻数字上. 如果你只用额外空间复杂度O(n)的条件下完成可以获得加分,其中n是数字三角形的总行数. 您在真实的面试中 ...
- 数字三角形(动态规划经典例题)
资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜 ...
- C语言数字三角形(动态规划)
题目 总时间限制: 1000ms 内存限制: 65536kB 描述 图1给出了一个数字三角形.从三角形的顶部到底部有很多条不同的路径.对于每条路径,把路径上面的数加起来可以得到一个和,你的任务就是找到 ...
- 数字三角形问题 (动态规划初步)
问题描述: 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数. 从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来.如 ...
- 蓝桥杯 数字三角形 贪心+动态规划
参考代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; int data[105][105];in ...
- 数字三角形 计算最大路径 动态规划
以所经过的权值之和最大值为例进行说明. 行进的过程中,每次只有两种选择:向左或向右.一个有n层的数字三角形的完整路径有2n条,所以当n比较大的时候,搜索全部路径,从中找出最大值,效率较低. 采用动态规 ...
- 【算法】【动态规划篇】第3节:数字三角形问题
本期任务:介绍算法中关于动态规划思想的几个经典问题 [算法][动态规划篇]第1节:0-1背包问题 [算法][动态规划篇]第2节:数字矩阵问题 [算法][动态规划篇]第3节:数字三角形问题 [算法][动 ...
- 经典算法——数字三角形的三种解题方法:递推、记忆化搜索、动态规划
上题目链接: http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Index/problemdetail/pid/1730.html 递推方法: i ...
- 数字三角形问题(动态规划)
目录 问题描述 分析 问题描述 问题描述:给定一个由n行数字组成的数字三角形,如图所示.图数字三角形试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大. 算法设计:对于给定的 ...
最新文章
- 通过全备+relaylog同步恢复被drop的库或表
- 【AngularJS学习笔记】Java Script use strict 严格模式
- flymcu无法打开串口_西门子1200与其他PLC/组态软件无线串口通讯(自由口)
- 代码合并工具_分享几款比较常用的代码比较工具
- DeepMind新突破:雷神之锤3战场AI夺旗,团战胜率超过人类
- phonegap走起
- Tensorflow如何读取文件
- dnf服务器运行库,游戏运行库|3DM游戏必备运行库合集安装包(史上最全) V3.0
- Pix2Pix代码解析
- html小写罗马字符怎么写,如何在 LATEX 中插入大小写的罗马字符
- unity 射线检测真机失效_Unity 2019 射线检测失效
- 返利商城系统开发功能模式解析
- android shareSDK 微博分享案例
- 互联网开发搞手游创作1-为何有这想法
- python 调试,Python 学习入门--pydev调试
- UNIX环境编程学习笔记(1):——出错处理errno
- python怎么加逗号_python – 什么是最简单的方法添加逗号到一个整数?
- Jenkins + fastlane + pgyer
- 银行舆情监测怎么做?
- 腾讯面试官:矩阵中的路径怎么求?
热门文章
- 雷蛇zGold与Nexon America建立全球合作伙伴关系
- 使用 Matlab 解决数学建模问题
- Himall商城ExpressDaDaHelper订单预发布 查询运费后发单接口
- mysql查询语句ppt_mysql简单查询.ppt
- mac dreamveaver cc破解方法
- 研究生“计算机通信新技术”课程复习题(2016年)
- 关于硕士毕业论文的思路整理
- Windows 8系统IE10无法安装Flash Player插件的解决办法
- html点击打开word文档,javascript打开word文档的方法
- SQL FULL OUTER JOIN