文章目录
898. 数字三角形
题目描述
给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输入格式:
第一行包含整数n ,表示数字三角形的层数。
接下来n 行,每行包含若干整数,其中第i 行表示数字三角形第i 层包含的整数。
输出格式:
输出一个整数,表示最大的路径数字和。
数据范围
1 ≤ n ≤ 500
− 10000 ≤ 三 角 形 中 的 整 数 ≤ 10000
输入样例:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例:
30
动态规划
代码的目的是解决数字三角形的问题,即找到从顶部到底部路径上数字总和最大的值。
#include<bits/stdc++.h> // 包含C++标准库的所有头文件
using namespace std; // 使用标准命名空间
// 声明两个二维数组a和dp,分别用于存储数字三角形的数值和动态规划的状态
int a[510][510];
int dp[510][510];
int main()
{
int n; // 声明整数变量n,表示数字三角形的层数
cin>>n; // 从标准输入读取层数
// 读取数字三角形中的数值
for(int i=1;i<=n;i++) // 外层循环遍历每一层
for(int j=1;j<=i;j++) // 内层循环遍历当前层的每个数
cin>>a[i][j]; // 读取并存储数字三角形中的数值
// 初始化dp数组,将其元素设为INT_MIN(整数的最小可能值)
for(int i=0;i<=n;i++)
for(int j=0;j<=i+1;j++) // 这里要多初始化一列,因为状态转移会用到j+1
dp[i][j]=INT_MIN;
// 初始化数字三角形顶部的dp值
dp[1][1]=a[1][1]; // 顶部的最大路径和就是顶部的值
// 动态规划计算最大路径和
for(int i=2;i<=n;i++) // 从第二层开始,计算每层的最大路径和
for(int j=1;j<=i;j++) // 遍历当前层的每个数
// 状态转移方程,比较从左上和正上方来的路径,选择一个最大的路径和
dp[i][j]=max(dp[i-1][j-1]+a[i][j],dp[i-1][j]+a[i][j]);
// 寻找最大的路径和
int res=0; // 用于存储最大路径和的变量
for(int i=1;i<=n;i++) // 遍历最后一层
for(int j=1;j<=i;j++) // 遍历最后一层的每个数
res=max(res,dp[i][j]); // 更新最大路径和
cout<<res; // 输出最大路径和
return 0; // 程序结束
}
这段代码首先使用一个双重循环读取输入的数字三角形,然后使用了动态规划的方法来求解问题。动态规划数组dp
在初始化时除了根据三角形的每一层设置INT_MIN
外,还额外初始化了一列,这是因为状态转移时可能会使用到dp[i-1][j]
,其中j
可能会等于i
。
动态规划的核心在于dp[i][j]
的更新过程,它代表了到达第i
层第j
个数字时可能得到的最大路径和。对于数字三角形的每一层的每一个数,其最大路径和等于它上一层左上方或正上方的最大路径和加上当前数值的较大者。
最后,在三角形的最后一层中找到最大的dp[i][j]
值,这就是整个数字三角形的最大路径和。程序以输出这个最大值结束。