问题描述:
7
3 8
8 1 0
2 7 4 4
在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或右下走。只需要求出这个最大和即可,不必给出具体路径。
三角形的行数大于1小于等于100,数字为0~99.
输入格式:
4 ///三角形的行数。下面是三角形
7
3 8
8 1 0
2 7 4 4
要求输出最大和
第一种方法:利用递归(超时,原因是重复计算,时间复杂度是2n)
1 #include <iostream> 2 #include <algorithm> 3 #define Max 101 4 using namespace std; 5 int D[Max][Max]; 6 int n; 7 int MaxSum(int i,int j) 8 { 9 if(i==n) 10 return D[i][j]; 11 int x=MaxSum(i+1,j); 12 int y=MaxSum(i+1,j+1); 13 return max(x,y)+D[i][j]; 14 } 15 int main() 16 { 17 int i,j; 18 cin>>n; 19 for(i=1;i<=n;i++) 20 for(j=1;j<=i;j++) 21 { 22 cin>>D[i][j]; 23 } 24 cout<<MaxSum(1,1)<<endl; 25 return 0; 26 }
第二种方法是动态规划(用数组存放已经计算出来的值,避免重复计算,时间复杂度是n2)
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 #define Max 101 5 int D[Max][Max]; 6 int n; 7 int maxSum[Max][Max]; 8 int MaxSum(int i,int j) 9 { 10 if(maxSum[i][j]!=-1) 11 return maxSum[i][j]; 12 if(i==n) 13 maxSum[i][j]=D[i][j]; 14 else 15 { 16 int x=MaxSum(i+1,j); 17 int y=MaxSum(i+1,j+1); 18 maxSum[i][j]=max(x,y)+D[i][j]; 19 } 20 return maxSum[i][j]; 21 } 22 int main() 23 { 24 int i,j; 25 cin>>n; 26 for(i=1;i<=n;i++) 27 for(j=1;j<=i;j++) 28 { 29 cin>>D[i][j]; 30 maxSum[i][j]=-1; 31 } 32 cout<<MaxSum(1,1)<<endl; 33 return 0; 34 }
第三种方法:递归改为递推,从底往上计算
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 #define Max 101 5 int D[Max][Max]; 6 int n; 7 int maxSum[Max][Max]; 8 int main() 9 { 10 int i,j; 11 cin>>n; 12 for(i=1;i<=n;i++) 13 { 14 for(j=1;j<=i;j++) 15 cin>>D[i][j]; 16 } 17 for(int i=1;i<=n;i++) 18 maxSum[n][i]=D[n][i]; 19 for(int i=n-1;i>=1;i--) 20 for(int j=1;j<=i;j++) 21 { 22 maxSum[i][j]=max(maxSum[i+1][j],maxSum[i+1][j+1])+D[i][j]; 23 } 24 cout<<maxSum[1][1]<<endl; 25 return 0; 26 }
第四种方法:进行空间优化 将二维数组转变为一维数组向上翻滚
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 #define Max 101 5 int D[Max][Max]; 6 int n; 7 int *maxSum; 8 int main() 9 { 10 int i,j; 11 cin>>n; 12 for(i=1;i<=n;i++) 13 for(j=1;j<=i;j++) 14 { 15 cin>>D[i][j]; 16 } 17 maxSum=D[n];////maxSum指向第n行 18 for(int i=n-1;i>=1;i--) 19 for(int j=1;j<=i;j++) 20 { 21 maxSum[j]=max(maxSum[j],maxSum[j+1])+D[i][j]; 22 } 23 cout<<maxSum[1]<<endl; 24 return 0; 25 }
第五种方法是直接利用D[n]代替int maxsum[n]
第二种方法到第五种方法的时间复杂度都是n*n。