标签:user 体会 结果 转变 turn 题目 算法实现 三角形 count
1、实践题目
数字三角形
2、问题描述
给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。
3、算法描述
采用自底向上的动态规划算法,设b[i][j]为从第n行到当前元素第i行第j列的最大路径和,则该题目的最终结果为b[1][1],当i=n时,b[i][j]=a[i][j],因为最后一行元素的最大路径和为各元素本身,第n-1,n-2.....2,1行的元素最大路径和要么为左下方元素最大路径和与当前元素的和,要么为右下方元素最大路径和与当前元素的和,即b[i][j]=max(b[i+1][j]+a[i][j],b[i+1][j+1]+a[i][j])[1<=i<=n,1<=j<=i],由此得到递归方程。
算法实现:
1 #include<iostream> 2 using namespace std; 3 int MaxCount(int n,int a[][101]){ 4 int b[101][101]; 5 int j=1; 6 int i; 7 for(int k=n;k>=1;k--){//复制最后一行元素 8 b[n][k]=a[n][k]; 9 } 10 for(i=n-1;i>=1;i--){//从n-1行开始 11 for(j=1;j<=i;j++){//每行i列 12 if(b[i+1][j]<b[i+1][j+1])//取最大值 13 b[i][j]=b[i+1][j+1]+a[i][j]; 14 else b[i][j]=b[i+1][j]+a[i][j]; 15 } 16 } 17 return b[1][1]; 18 19 } 20 int main(){ 21 int n; 22 cin>>n; 23 int a[101][101]; 24 for(int i=1;i<=n;i++){ 25 for(int j=1;j<=i;j++){ 26 cin>>a[i][j]; 27 } 28 } 29 cout<<MaxCount(n,a); 30 return 0; 31 }
4、算法时间复杂度及空间复杂度分析
时间复杂度:双重循环,所以时间复杂度为O(N^2)
空间复杂度:用到二维数组,所以空间复杂度为O(N^2)
5、心得体会
这道题目虽然不是很难,但是对于我理解动态规划和自底向上有很大的帮助。首先我就犯了一个审题不清的错误,以为他的路径是可以随意走的,所以列出了错误的递归方程,后来在老师的提醒下才意识到只有左下角和右下角,但是意识到这一点之后,我一开始并没有想到自底向上,而是用的从上往下,然后我就发现其实到最后还是逼到了最后一行,既然如此,那不就完全可以从最后一行往上推?改变了思路之后,我发现问题变得很简单,递归方程也很容易就写出来了。这个思路的转变来自同学的提醒,所以有的时候当你发现自己思路好像有问题的时候一定要及时跟同学或者老师分享,也许他们就能指出你的问题所在,问题都是讨论出来的,学习的确不能只顾自己埋头。
标签:user 体会 结果 转变 turn 题目 算法实现 三角形 count
原文地址:https://www.cnblogs.com/huangroumin/p/9940045.html