Problem Description
在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:
有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
已经告诉你了,这是个DP的题目,你能AC吗?
有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
![](https://i-blog.csdnimg.cn/blog_migrate/79b65092734d6a263a9280f5b332c5b9.jpeg)
已经告诉你了,这是个DP的题目,你能AC吗?
Input
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。
Output
对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。
Sample Input
1 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
Sample Output
30
//c++
#include<iostream>
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std;
int main()
{
int n,i,j,c,a[10100];
cin>>c;
while(c--)
{
cin>>n;
int s=(n+1)*n/2;
for(i=1;i<=s;++i)
{
cin>>a[i];
}
for(i=s-n,j=0;i>=1;--i)
{
a[i]=a[i]+max(a[i+n-1],a[i+n]);
if(++j==n-1)
{
j=0;
--n;
}
}
cout<<a[1]<<endl;
}
return 0;
}
//C语言
#include <stdio.h>
#define N 10000
#define Max(a,b) ((a) > (b) ? (a) : (b))
int a[N];
int main()
{
int n,m,i,k,j;
scanf("%d",&m);
while(m-- > 0)
{
scanf("%d",&n);
k = (1 + n) * n / 2;
for(i = 1 ; i <= k; i++)
{
scanf("%d",a+i);
}
k = k - n;
for(i = k , j = 0 ; i >= 1 ; i--) //从下到上,从右到左加起来
{
a[i] = a[i] + Max(a[i+n],a[i+n-1]); // 因为每一个都是 相邻的,所以可以这样
if(++j == n-1)
{
n--;
j = 0;
}
}
printf("%d\n",a[1]);
}
return 0;
}