第三章算法上机实验报告

1.实践题目、

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

 

输入格式:

输入有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

  1. 问题描述、

就是给你一个三角形,每次只能往下走或者往右下走,选取值最大的路线。

  1. 算法描述

很假单的dp问题,但是问题是——要怎么想到用动态规划对吧。

一开始我是想每次贪心,取最大的值,比如我从开始走,走到3还是走到8呢?如果走8的话,那么8下面就只能往1和往0走了。

这样的话不能保证是最优的解吧?

然后也可以每一条路都走一遍,从7走到38变成两个子问题,这两个子问题又会生出四个子问题——是从3走到8呢还是从3走到1呢,就会有2^n次方种可能的结果,时间复杂度直接爆炸。

那么接下来就只能用到dp

从后面往前走的话,因为和最大,所以从每一个节点所取下面左右两边最大的的值,加起来,一层层往上遍历,一直到顶端,就可以知道结果。

所以时间复杂度是On^2)。

空间复杂度是On^2

代码实现:

#include<iostream>

#include<algorithm>

using namespace std;

 

int main(){

 int n;

    cin>>n;

    int a[200][200],i,j;

    for(i=0;i<n;i++){

     for(j=0;j<=i;j++){

        cin>>a[i][j];

  }

 }

 for(i=n-2;i>=0;i--){

  for(j=0;j<=i;j++){

   a[i][j] = max(a[i+1][j],a[i+1][j+1])+a[i][j];

  }

 }

 cout<<a[0][0]<<endl;

 return 0;

}

心得体会:

dp并不难,最难的是要怎么去dp。

posted on 2019-10-21 20:45  梁锋华  阅读(172)  评论(0编辑  收藏  举报