动态规划之求解三角形最小路径问题
求解三角形最小路径问题
一、【问题描述】:
给定 高度为n的一个整数三角形,找出从顶部到底部的最小路径和,只能向先移动相邻的结点。首先输入n,接下来的1~n行,第i行输入i个整数,输出分为2行,第一行为最小路径,第2行 为最小路径和。
例如,下图是一个n=4的三角形,输出的路径是2,3, 5, 3最小路径是13。
23 46 5 78 3 9 2
二、【问题求解】:
将三角形采用二维数组a存放
2
3 4
6 5 7
8 3 9 2
从顶部到底部查找最小路径,那么节点(i,j)的前驱结点只有(i-1,j-1)和(i-1, j)两个
使dp[i][j]表示从顶部a[0][0]查找到(i,j)节点时候的最小路径和,显然这里有两个边界,即第一列和对角线,达到它们中结点的路径只有一条而不是常规的两条。这个结论不能从我们构造的二维数组中观察而是要从示例中才能观察得出结论。
可得状态转移方程为:
dp[0][0]=a[0][0](顶部边界)
dp[i][0]=dp[i-1][0]+a[0][0] (1<=i<=n-1)
dp[i][i]=dp[i-1][i-1]+a[i][i](1<=i<=n-1)
dp[i][j]=min{dp[i-1][j-1],dp[i-1]}+a[i][j]
最后求出来的最小路径和为ans=min(dp[n-1][j]),以及对应的列号k
由dp求出一条路径的方法:
用pre[i][j]表示查找到(i,j)结点时最小路径上的前驱结点,由于前驱结点只有两个,即(i-1,j-1)和(i-1,j),用pre[i][j]记录前驱结点的列号即可。
在求出ans之后,通过pre[n-1][k]反推求出方向路径,最后正向输出该路径。
代码实现:
#include<bits/stdc++.h>
using namespace std;
int a[100][100];
int n;
int dp[100][100];
int pre[100][100];
int ans=0;
int search(){ //求解最小路径和ans int i,j;dp[0][0]=a[0][0];for(i=1;i<n;i++){ //考虑第1列的边界 dp[i][0]=dp[i-1][0]+a[i][0];pre[i][0]=i-1;}for(i=1;i<n;i++){ //考虑对角线的边界 dp[i][i]=a[i][i]+dp[i-1][i-1];pre[i][i]=i-1;}for(i=2;i<n;i++){ //考虑其他有两条达到路径的结点 for(j=1;j<i;j++){if(dp[i-1][j-1]<dp[i-1][j]){pre[i][j]=j-1;dp[i][j]=a[i][j]+dp[i-1][j-1];}else{pre[i][j]=j;dp[i][j]=a[i][j]+dp[i-1][j];}}}ans=dp[n-1][0];int k=0;for(j=1;j<n;j++){ //求出最小ans和对应的列号k if(ans>dp[n-1][j]){ans=dp[n-1][j];k=j;}}return k;
}
void Dispath(int k) //输出最小和路径
{int i = n - 1;vector<int> path;//存放逆路径向量path while (i >= 0) //从(n-1,k)结点反推求出反向路径 {path.push_back(a[i][k]);k = pre[i][k]; //最小路径在前一行中的列号 i--; //在前一行寻找 }vector<int>::reverse_iterator it; //定义反向迭代器 for (it = path.rbegin(); it != path.rend(); ++it)cout << *it << " "; // 反向输出构成正向路径
}
int main(){int k;memset(pre,0,sizeof(pre));memset(dp,0,sizeof(dp));scanf("%d",&n);for(int i=0;i<n;i++)for(int j=0;j<=i;j++)scanf("%d",&a[i][j]);k=search();Dispath(k);printf("最小路径和为:")printf("%d\n",ans);return 0;
}
参考自《算法设计与分析》第二版 李春葆
动态规划之求解三角形最小路径问题相关推荐
- 动态规划法求解三角形最小路径问题
问题描述 给定高度为n的一个整数三角形,找出从顶部到底部的最小路径和,只能向先移动相邻的结点.首先输入n,接下来的1-n行,第i行输入i个整数,输出分为2行,第一行为最小路径,第2行为最小路径和. 例 ...
- leetcode--笔记——120. 三角形最小路径和
120. 三角形最小路径和 给定一个三角形 triangle ,找出自顶向下的最小路径和. 每一步只能移动到下一行中相邻的结点上.相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一 ...
- leetcode - 120. 三角形最小路径和
120. 三角形最小路径和 ------------------------------------------ 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如 ...
- 算法:三角形最小路径和
题目 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [[2],[3,4],[6,5,7],[4,1,8,3] ] 1 2 3 4 5 6 自顶向 ...
- Java 练习 1.三角形最小路径和 2.外出采摘的日本人 3.最大矩形
三角形最小路径和 给定一个三角形 triangle ,找出自顶向下的最小路径和. 每一步只能移动到下一行中相邻的结点上.相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 ...
- 三角形最小路径和(动态规划)
原创公众号:bigsai 欢迎加入力扣打卡 文章已收录在 全网都在关注的数据结构与算法学习仓库 欢迎star 题目描述 力扣120原题 给定一个三角形 triangle ,找出自顶向下的最小路径和. ...
- leetcode120. 三角形最小路径和(动态规划)
**给定一个三角形,找出自顶向下的最小路径和.**每一步只能移动到下一行中相邻的结点上. 相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点. 例如, ...
- [Leetcode][第120题][JAVA][三角形最小路径和][动态规划][递归]
[问题描述][中等] [解答思路] 1. 动态规划思路一 自上而下 第 1 步:设计状态 f[i][j] 表示从三角形顶部走到位置 (i,j) 的最小路径和 位置(i,j) 指的是三角形中第 i 行第 ...
- LeetCode 120. 三角形最小路径和(动态规划)
题目描述 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径 ...
最新文章
- css调整表格在屏幕上的位置
- WebDAV服务漏洞利用工具DAVTest
- python isnumeric函数用法_Python中isnumeric()方法的使用简介
- ASP.NET MVC 5 - 将数据从控制器传递给视图
- Android Prefence 总结
- 2.Flask-jinjia2模板
- amos调节变量怎么画_AMOS 中验证性因素分析(CFA)
- QtDesigner如何添加工具栏toolBar
- 共享内存之——system V共享内存
- 金蝶移动bos开发教程_金蝶bos
- review board 使用
- 【DBSCAN聚类算法原理介绍】
- 【树莓派 + 深度学习 + Python】从零开始做一个你画AI猜的小游戏
- c++ 线程函数(类成员函数作为线程函数使用)
- API监控平台,统一监控系统API
- ai人工智能将替代人类_AI再次击败人类
- 还房贷最省钱的理财方法(转自微信公众号——紫竹张先生)
- OC视频笔记7(自定义初始化方法)8(类方法与实例方法的区别)(为什么NSString后面加*)
- 行人重识别(ReID) ——数据集描述 DukeMTMC-reID
- 阿里云盘正式公测!附下载地址及2T免费存储空间