数学三角形(简单dp)

大家请先看题
题目描述
观察下面的数字金字塔。

写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

输入格式
第一个行一个正整数 rr ,表示行的数目。

后面每行为这个数字金字塔特定行包含的整数。

输出格式
单独的一行,包含那个可能得到的最大的和。、
输入输出样例
输入 输出
5 30
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

本题解法并非唯一,以下只是其中一种;
在此讲一下从下往上推的做法。//因为更直观,从上往下推同理可推了

步骤:

(1)读入;

(2)num[i][j]代表从下往上到达i行j列这个点所能达到的和的最大值,

核心步骤:
num[i][j]+=max(num[i+1][j],num[i+1][j+1]);;//(i+1)意思是i下面的那行数字 j和(j+1)作比较选择大值 然后选择max括号内最大值 与 i 相加就此递推上去;
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
从下向上推导:
第五层:4 += max(4,5) -> 7 += max(5,2) -> 4 +=max(2,6) -> 4+=(6,5)
第四层:9 12 10 10
第三层:8 += max(9,12)-> 1 += max(12,10)-> 0 += max(10,10)
第二层:3 += max(20,13)-> 8 += max(13,10)
第一层:7 += max(23,21)
输出:30

话不多说看代码
#include
using namespace std;
int n;
int num[100][100];
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
for(int j=0;j<=i;j++)
scanf("%d",&num[i][j]);//以上输入
for(int i=n-1;i>=0;i–)
{
for(int j=0;j<=i;j++)//for循环按顺序扫描除最后一排前的所有数
num[i][j]+=max(num[i+1][j],num[i+1][j+1]);
//从左下,右下中选取大的加到现在的位置上
}
cout<<num[0][0];
return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_45531709/article/details/107604154