问题描述:
在讲述DP算法的时候,一个经典的例子就是数塔问题
有形如下图所示的数塔,从顶部出发,在每一结点可以选择向左走或是向右走,一直走到底层,要求找出一条路径,使路径上的值最大。
输入:
整数N表示数塔的高度,接下来用N行数字表示数塔,其中第i行有i个整数
输出:
路径中最大的和
分析:
自顶向下的分析,确实太暴力了,假设有31行,则有2^30条路径,会发现从上往下总要先知道该路径上所有值的和,比较后才可确定,
换种思路,从下往上比较,;例如上例,最后一行,19>7,故舍掉7,2变成2+19=21;同理7<10,18变成18+10=28......以此类推.....
代码://最后输出时注意下回车,该题是最后一个数也要回车换行
#include<iostream>
using namespace std;
int main()
{
int c,i,j,t;
int dp[100][100];
cin>>c;//表示实例个数
int *a=new int[c];//动态定义数组
for(t=0;t<c;t++)
{
memset(dp,0,sizeof(dp));
cin>>a[t];
for(i=0;i<a[t];i++)
{
for(j=0;j<i+1;j++)
{
cin>>dp[i][j];//输入数据
}
}
for(i=a[t]-1;i>0;i--)
{
for(j=0;j<i;j++)
{
if(dp[i][j]<=dp[i][j+1]) dp[i-1][j]+=dp[i][j+1];
else dp[i-1][j]+=dp[i][j]; //由下往上每一行逐个比较,较小的这一分支会去掉,并且把数值之和放到上一行
}
}
a[t]=dp[0][0];//最顶端的数字存放的是由下往上累计上来的为最终的和
}
for(t=0;t<c;t++)
{
//if(t==c-1) cout<<a[t];
//else
cout<<a[t]<<endl;
}
delete a;//释放动态内存
return 0;
}