C++动态规划算法之数字三角形系列问题:数塔及其变种

来源:互联网 发布:java 计算时间差 分钟 编辑:程序博客网 时间:2024/06/05 13:23

数字三角形系列问题

数字三角形I

题目描述

考虑在下面被显示的数字金字塔。 写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大。每一步可以走到左下方的点也可以到达右下方的点。

 

在上面的样例中,从7 到 3 到 8 到 7 到 5 的路径产生了最大和:30

输入

第1行:1个整数R(1<= R<=1000),表示行的数目。

接下来共R行,第i行有i个整数。所有的数均非负的且不大于100。

输出

第1行:可以得到的最大的和。

样例输入

573 88 1 02 7 4 44 5 2 6 5

样例输出

30

思路解析

下面是每个点到底层可以得到的最大数值:

30

23 21

20 13 10

7  12 10 10

4  5  2  6  5

代码实现

#include<cstdio>#include<algorithm>using namespace std;int r,a[1002][1002],F[1002][1002];main(){scanf("%d",&r);for(int i=1;i<=r;i++)for(int j=1;j<=i;j++){scanf("%d",&a[i][j]);F[i][j]=a[i][j];}for(int i=r-1;i>0;i--)for(int j=1;j<=i;j++)F[i][j]+=max(F[i+1][j],F[i+1][j+1]);printf("%d",F[1][1]);}

数学三角形II

题目描述


输入

第1行:1个整数N,表示数字三角形的行数和列数(1 <= N <= 1000)

接下来N行,第i行有i个整数,表示数字三角形

输出

第1行:1个整数,表示问题的最优解

样例输入

513 69 9 15 5 2 32 9 7 6 1

样例输出

30

思路解析

下面是每个点到底层可以得到的最大数值:

30
26 29
23 23 15
14 14 11 12

代码实现

#include<bits/stdc++.h>using namespace std;int n,a[1002][1002],F[1002][1002],G[1002][1002];main(){scanf("%d",&n);for(int i=1;i<=n;i++)for(int j=1;j<=i;j++){scanf("%d",&a[i][j]);F[i][j]=a[i][j];}for(int i=n-1;i>0;i--)for(int j=1;j<=i;j++){F[i][j]+=max(F[i+1][j],F[i+1][j+1]);G[i][j]=max(*max_element(F[i+1]+1,F[i+1]+i+2),max(G[i+1][j],G[i+1][j+1]))+a[i][j];}printf("%d",max(F[1][1],G[1][1]));}

数字三角形III

题目描述


输入

第1行:1个整数N,表示数字三角形的行数和列数(1 <= N <= 1000)
接下来N行,第i行有i个整数,表示数字三角形

输出

第1行:1个整数,表示问题的最优解 第1行:1个整数,表示问题的最优解

样例输入

500 10 1 01 0 0 00 0 0 1 0

样例输出

3

思路解析

下面是每个点到底层可以得到的最大数值:

3

2 31 2 11 0 1 10 0 0 1 0

代码实现

#include<cstdio>#include<algorithm>using namespace std;int n,a[1002][1002];bool F[1002][1002][11];main(){    scanf("%d",&n);    for(int i=1;i<=n;i++)        for(int j=1;j<=i;j++)            scanf("%d",&a[i][j]);for(int j=1;j<=n;j++) F[n][j][a[n][j]%10]=1;    for(int i=n-1;i>0;i--)        for(int j=1;j<=i;j++)for(int k=0;k<10;k++)if(F[i+1][j][k]||F[i+1][j+1][k])F[i][j][(k+a[i][j])%10]=1;    for(int i=9;i>=0;i--)if(F[1][1][i]){printf("%d\n",i);break;}}

原创粉丝点击