数字三角形(dp入门题目)

给定一个如下图所示的数字三角形,从顶部出发,在每一结点可以选择移动至其左下方的结点或移动至其右下方的结点,一直走到底层,要求找出一条路径,使路径上的数字的和最大。
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

这是一道非常经典的题目,从这道题目可以衍生出很多别的题型。这也是我们学习dp的一个入门题目。
题目分析:
dp问题要从状态表示(设定状态方程中每个数表示什么)和状态计算(状态方程是什么)两方面入手

  1. 状态表示:因为这道题要求的是到达底层的的最大路径数字之和。因此我们可以设出一个方程,求出走到每一个点的最大路径数字之和。这样状态就可以表示了f[i][j] //表示从起点走到(i,j)的最大路径数组和
  2. 注:因为底层有n个数字,在求解答案时需要遍历底层的所有数,因此我们可以反过来进行求解,这样从底层走到最高层路径数字之和就一定为f[0][0] 。
  3. 状态计算:当要移动到(i,j)点时,它只能够从该点的左下或右下方移动过去,即从 f[i+1][j+1]和f[i+1][j]移动过去。而f[i+1][j+1]和f[i+1][j]均为到达(i+1,j+1)和(i+1,j)的最大值,因此到达(i,j)的路径数字和的最大值只需要找到f[i+1][j+1]和f[i+1][j]的最大值即可。状态转移方程即为f[i][j]=max(f[i+1][j+1],f[i+1][j])+(i,j)点的数字

代码如下:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <iomanip>
#define LL long long
using namespace std;
const int N=505;
int main()
{
    int n,f[N][N]={0};
    cin>>n;
    for(int i=0;i<n;i++)   //初始化f[i][j],将(i,j)点的值提前保持在
    for(int j=0;j<=i;j++)  //f[i][j]中
    cin>>f[i][j];
    
    for(int i=n-2;i>=0;i--)  //递推法从下往上找最大值
    for(int j=0;j<=i;j++)
    f[i][j]+=max(f[i+1][j+1],f[i+1][j]);
    
    cout<<f[0][0]<<endl;   //f[0][0]即为最大值
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lwz_159

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值