题目:题目链接
题目描述:
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1)Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.
题意;图1显示了一个数字三角形。编写一个程序,计算从顶部开始到底部某处的路径上传递的最大数字总和。每个步骤可以沿对角线向下滑动,也可以沿斜向下滑动到右侧。
Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.
Output
Your program is to write to standard output. The highest sum is written as an integer.
Sample Input
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5Sample Output
30
思路1:递归MaxSum(i,j) = max(MaxSum(i+1,j),MaxSum(i+1,j+1))+D[i][j];加上递归出口,if i == n MaxSum(i,j) = D[i][j](说明已经到了最后一行,直接返回即可) (TLE)
思路2;
7(1)
3 (1) 8(1)
8(1) 1(2) 0(1)
2(1) 7(3) 4(3) 4(1)
4(1) 5(4) 2(6) 6(4) 5(1)
从图中发现,第一中方法递归重复计算了很多数据,导致时间复杂度升高,为了解决重复计算的问题,采用记忆化搜索,将已经计算过的数据保存至一个数组中,当需要再次使用时,至于要直接拿出来用即可,无需重复计算,if maxSum[]i[j] != -1,说明没有计算,然后按思路1的过程计算maxSum[i][j],如果已经计算过了,直接return maxSum[i][j].(AC)
思路三:
用循环递推来计算maxSum数组,maxSum[n][i] = D[n][i](i>=1&&i<=n),maxSum[i][j] = max(maxSum[i+1][j],maxSum[i+1][j+1])+ D[i][j] (AC)
思路一代码:
/*
题目链接:https://vjudge.net/problem/POJ-1163
分类:递归
*/
#include <iostream>
using namespace std;
const int MAX = 101;
int n;
int D[MAX][MAX];
int MaxSum(int i,int j)
{
if(i == n) return D[i][j];//已到最后一行
else{
return max(MaxSum(i+1,j),MaxSum(i+1,j+1))+D[i][j];
}
}
int main()
{
cin>>n;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= i;j++){
cin>>D[i][j];
}
}
cout<<MaxSum(1,1)<<endl;
}
思路二代码:
/*
题目链接:https://vjudge.net/problem/POJ-1163
分类:DP 递归
*/
#include <iostream>
using namespace std;
const int MAX = 101;
int n;
int D[MAX][MAX];
int maxSum[MAX][MAX];
int MaxSum(int i,int j)
{
if(maxSum[i][j]!=-1) return maxSum[i][j];
if(i == n) maxSum[i][j] = D[i][j];//已到最后一行
else{
maxSum[i][j] = max(MaxSum(i+1,j),MaxSum(i+1,j+1))+D[i][j];
}
return maxSum[i][j];
}
int main()
{
cin>>n;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= i;j++){
cin>>D[i][j];
maxSum[i][j] = -1;
}
}
cout<<MaxSum(1,1)<<endl;
}
思路三代码;
#include <iostream>
const int MAX = 101;
using namespace std;
int n;
int D[MAX][MAX];
int MaxSum[MAX][MAX];
int main(){
cin>>n;
for(int i = 1;i <= n;i++){
for(int j = 1;j <= i;j++){
cin>>D[i][j];
}
}
for(int i = 1;i <= n;i++){
MaxSum[n][i] = D[n][i];
}
for(int i = n-1;i >= 1;i--){
for(int j = 1;j <= i;j++){
MaxSum[i][j] = max(MaxSum[i+1][j],MaxSum[i+1][j+1]) + D[i][j];
}
}
cout<<MaxSum[1][1]<<endl;
return 0;
}