算法第三章上机实践报告——动态规划

实践报告——第一题

1、实践题目

数字三角形

 

2、问题描述

给定一个由 n行数字组成的数字三角形如下图所示。试设计一个算法,计算出从三角形 的顶至底的一条路径(每一步可沿左斜线向下或右斜线向下),使该路径经过的数字总和最大。

QQ截图20170929023616.jpg

输入格式:

输入有n+1行:

第 1 行是数字三角形的行数 n,1<=n<=100。

接下来 n行是数字三角形各行中的数字。所有数字在0..99 之间。

输出格式:

输出最大路径的值。

输入样例:

在这里给出一组输入。例如:

5 
7 
3 8 
8 1 0 
2 7 4 4
4 5 2 6 5 

输出样例:

在这里给出相应的输出。例如:

30

3、算法描述
这是道动态规划的题目,使用动态规划的思想,把问题一步一步细分,寻找子问题的最优解。
对这道题来说,子问题就是从最底下的相邻数字的和算起,即一步一步往上运算,每一步都满足最小这个条,到第一行的时候就是最后的解。
实现这一操作则需要归纳出递归方程:
Max[i][j] = A[i][j]+max(Max[i+1][j],Max[i+1][j+1])
然后进行填表操作,二维数组,自下而上,自左往右。
 
4、算法时间及空间复杂度分析
时间复杂度:o(n*n),填表时使用了二维数组,则用到了两层循环,所以时间复杂度是n的平方。
空间复杂度:在主函数中,给变量分配的空间为常数,所以空间复杂度为o(l)。
 
5、心得体会
第一次接触动态规划,有点难理解,没怎么会往那个方向去想题目。然后慢慢看题目,不知道怎么得出递归方程,最后和同伴数学分析,慢慢尝试,用数学运算得出了规律,最后得出了递归方程,就开始用动态规划的套路实现这个递归方程了。最后做出之后挺有成就感的,这次和小伙伴配合很棒,大家有各自的思考,可以互补对方思考的空缺。虽然这次一节课只完成了这一道题,但这也算是动态规划的典型例子了,还是很有成就感的。应该课后多点实践,缺少刷题,对动态规划的熟悉还不够。
 
#include<iostream>
using namespace std;

int main(){
     int n,a=1;
     cin>>n;
     int A[101][101];
     for(int i = 1;i<=n;i++){
         for(int j=1;j<=n;j++){
            A[i][j]=0;
         }
     }
    
     for(int i=1;i<=n;i++){
        for(int j=1;j<=a;j++){
     cin>>A[i][j];
             }  
             a++;       
         }
        
       
     int Max[101][101];
     for(int j=1; j<=n; j++){
        Max[n][j]=A[n][j];
     }
     for(int i=n-1; i>0; i--){
        for(int j=1; j<=i; j++){
            if((Max[i+1][j+1])<Max[i+1][j]){
                Max[i][j] = A[i][j]+Max[i+1][j];
            }
             else Max[i][j] = A[i][j]+Max[i+1][j+1];
        }
     }
     cout<<Max[1][1];
     return 0;
}            
 
posted @ 2019-10-20 22:04  ErwinGluttony  阅读(175)  评论(0编辑  收藏  举报