Problem Description
在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:<br><br>有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?<br><img src=../data/images/2084-1.jpg><br>已经告诉你了,这是个DP的题目,你能AC吗?
Input
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。<br>
Output
对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。<br>
Sample Input
1 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
(1)题目大意:
本题讲述的是经典数塔问题,就是相邻的可以走,从顶层到底层,哪条路线权值相加是最大的。
(2)思路: 有两种,一种是从上到下的走法,还有一种是从下到上的。我这里是从下到上的,因为这个更简便。用一个二维数组存储该结构,我们发现从下到上,k层的每个值都对应k+1层的相邻两个值。所以我们取二者最大的给k层。以此类推,循环进行下去,第一层的值就是所有路径最大值,槪题有点像贪心算法。
(3)感想:
题目简单,但是得需要仔细。对于一样的题,任何方法可能都可以实现,但是步骤不一样,因而就会有最优的,比如数塔,可以从上到下,但是你要判断边界问题,代码不但长,而且运算时间夜场,不是最优的,相对的从下到上就更简单方便。
(4)代码:
#include<iostream>
using namespace std;
int main()
{
int n, m, c;
int a[100][100];//建立一个二维数组
cin >> c;//要测试的组数
int max(int m, int n);
while (c--)
{
cin >> n;//每组的行数
for (int i = 0;i < n;i++)
{
for (int j = 0;j <= i;j++)
{
cin>>a[i][j];//插入数据
}
}
//从下往上的加
for (int j = n - 2; j >= 0;j--)
{
for (int i = 0;i <= j;i++)
{
a[j][i] += max(a[j+1][i], a[j+1][i+1]);
}
}
cout << a[0][0] << endl;
}
return 0;
}
int max(int m, int n)
{
return m > n ? m : n;
}