数字三角形问题
Time Limit: 1000 ms Memory Limit: 65536 KiB
Problem Description
给定一个由n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形的顶至底的一条路径,使该路径经过的数字总和最大。
对于给定的由n行数字组成的数字三角形,计算从三角形的顶至底的路径经过的数字和的最大值。
Input
输入数据的第1行是数字三角形的行数n,1≤n≤100。接下来n行是数字三角形各行中的数字。所有数字在0…99之间。
Output
输出数据只有一个整数,表示计算出的最大值。
Sample Input
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Sample Output
30
解法一:普通递归(OJ超时)
**
用二维数组存放数字三角形。
D( r, j) : 第r行第 j 个数字(r,j从1 开始算)
MaxSum(r, j) : 从D(r,j)到底边的各条路径中,最佳路径的数字之和。
问题:求 MaxSum(1,1)
典型的递归问题。
D(r, j)出发,下一步只能走D(r+1,j)或者D(r+1, j+1)。故对于N行的三角形:
#include<bits/stdc++.h>
using namespace std;
const int Max = 111;
int dp[Max][Max];
int num;
int maxsum(int i, int j)
{
if(i == num)
return dp[i][j];
int x = maxsum(i + 1, j);
int y = maxsum(i + 1, j + 1);
return max(x, y) + dp[i][j];
}
int main()
{
int i, j;
cin >> num;
for(i = 1; i <= num; i ++)
for(j = 1; j <= i; j ++)
cin>>dp[i][j];
cout<<maxsum(1, 1)<<endl;
return 0;
}
解法二:动归
注意:该题从下到上计算,num - 1开始,因为有i+1,j+1,如果从num开始,越界了
#include<bits/stdc++.h>
using namespace std;
const int Max = 101;
int dp[Max][Max];
int num;
int maxsum(int num)
{
for(int i = num - 1; i >=1 ; i--)///这里从下到上计算,num - 1开始,因为有i+1,j+1,如果从num开始,越界了
{
for(int j = 1; j <= i; j++)
{
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + dp[i][j];
}
}
return dp[1][1];
}
int main()
{
cin>>num;
for(int i = 1; i <= num; i++)
for(int j = 1; j <= i; j++)
cin>>dp[i][j];
cout<<maxsum(num)<<endl;
return 0;
}