观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
在上面的样例中,从 7→3→8→7→57→3→8→7→5 的路径产生了最大权值。
输入格式
第一个行一个正整数 𝑟r ,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
输出格式
单独的一行,包含那个可能得到的最大的和。
#include<bits/stdc++.h>
using namespace std;
int a[1010][1010];
int dp[1010][1010];
int main()
{
int r;
cin>>r;
for(int i=1;i<=r;i++)
{
for(int j=1;j<=i;j++)
{
cin>>a[i][j];
}
}
for(int i=1;i<=r;i++)
{
for(int j=1;j<=i;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i][j];
}
}
int ans=0;
for(int i=1;i<=r;i++)ans=max(ans,dp[r][i]);
cout<<ans;
}
题目问:怎么找到顶点到最下面一层,并使得这路上的点之和最大。
设dp[i][j]为从顶点走到i行j列的点,路程的最大值。
那么从顶点走到第r行(题目要求),的值为dp[r][i](i=1,2,3,4,5,...r),找到max(dp[r][i])就是答案,因为dp[r][i]为从顶点走到第r层每一个点,分别的路程最大值。
下面来看一张图
假如我想求从顶点到黄色的点,路程最大值。
根据题目的走法,黄色的点要么从蓝色的点向下走一步,要么由绿色的点向下走得到。
设黄色位置为(i,j),那么绿色和蓝色位置分别为(i-1,j-1),(i-1,j)。顶点到绿色和黄色点的距离最大值分别为dp(i-1,j-1)和dp(i-1,j)。当想求顶点到黄色点的最大值是,有两种选择,第一先走到绿色点距离为dp(i-1,j-1)再加上黄色点自己的值a[i][j],第二先走到蓝色点距离为dp(i-1,j)再加上黄色点自己的值a[i][j]。
所以有dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])+a[i][j];
接下来通过循环得到dp[r][i](i=1,2,3,...r)即可。
觉得写得还行可以求一个免费的赞吗~