一道水题。
观察下面的数字金字塔。写一个程序查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以从当前点走到左下方的点也可以到达右下方的点。
在上面的样例中,从13到8到26到15到24的路径产生了最大的和86。
Input
第一个行包含R(1≤ R≤1000),表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
所有的被供应的整数是非负的且不大于100。
Output
单独的一行,包含那个可能得到的最大的和。
Sample Input 1
5 86
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
Sample Output 1
86
——摘自YCOJ
这道题不是很难,其目的就是从上往下叠加值,并比较求最大值,通过路径我们可以得知它又左右两种选择(如图)画到手酸
由图可知,将和的最大支值比较就可以了,就用顺推做吧(或许可以深搜)。
日常万能头文件:
#include<bits/stdc++.h>
using namespace std;
int r;
int a[1010][1010],dp[1010][1010];
int maxn=0;
输入二维数组:
cin >>r;
for(int i=1;i<=r;i++){
for(int j=1;j<=i;j++){
cin >> a[i][j];
}
}
不想打了,直接出代码:
#include<bits/stdc++.h>
using namespace std;
int r;
int a[1010][1010],dp[1010][1010];
int maxn=0;
int main(){
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++){
if(dp[i-1][j]>dp[i-1][j-1]){
dp[i][j]=dp[i-1][j]+a[i][j];
}else{
dp[i][j]=dp[i-1][j-1]+a[i][j];
}
}
}
for(int i=1;i<=r;i++){
if(dp[r][i]>maxn){
maxn=dp[r][i];
}
}
cout << maxn;
return 0;
}
同时,亦可以用逆推(如图):
将数字从下往上叠加,最后比较,求出最大值。
代码如下:
#include<bits/stdc++.h>
using namespace std;
int r;
int a[1010][1010],dp[1010][1010];
int maxn;
int main(){
cin >>r;
for(int i=1;i<=r;i++){
for(int j=1;j<=i;j++){
cin >> a[i][j];
}
}
for(int i=r;i>=1;i--){
for(int j=1;j<=i;j++){
dp[i][j]=max(dp[i+1][j],dp[i+1][j+1])+a[i][j];
}
}
cout << dp[1][1];
return 0;
}