数字三角形(C语言)

一、问题描述
给定一个由行数字组成的数字三角形。试着设计一个算法,计算出从三角形的顶到底的一条路径,使得该路径经过的数字总和最大,并分析算法的计算复杂性。如下图所示:
7
3 8
8 1 0
   2 7 4 4
   4 5 2 6 5

二、问题分析及算法描述(包含主要变量和函数功能介绍)
设a(i,j)表示数字三角形中的第i行第j个点。 max[i][j]表示第i行第j个数字到低端的最佳路径之和,则原问题的解就是max[1][1]的值了。 从a(i,j)这个点向下走,显然只能走a(i+1,j)和a(i+1,j+1)这两个点了。而max[i][j]的最优值=a(i,j)的值+max{. max[i+1][j],max[i+1][j+1] }o 所以,我们可以至底向,上来计算。先计算最后一层的点的,然后倒二层的,…一直算到第一层。
递推方程:

三、源程序及程序说明文件

#include "stdafx.h"
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<iostream>
using namespace std;-·
int a[110][110];
int max[110][110];
int n;
int MaxSum(int n)
{
 for (int i = n; i >= 1; i--)
{
 max[n][i] = a[n][i];//初始化,最下面一层的max数组就是三角形最下面一层的值
}
for (int i = n - 1; i >= 1; i--)
{//从倒数第二层向上计算
 for (int j = 1; j <= i; j++)
{//计算第 i 层的每一个点的 max[][]
 if (max[i + 1][j + 1]>max[i + 1][j])
{
 max[i][j] = max[i + 1][j + 1] + a[i][j];//要么向下一层上和它最近的右边走
}
 else
max[i][j] = max[i + 1][j] + a[i][j];//要么向下一层上和它最近的左边走
 }
 }
return max[1][1];
}
int main()
{
 cin >> n;
 for (int i = 1; i <= n; i++)
 { 
 for (int j = 1; j <= i; j++)
 { 
 cin >> a[i][j];
 }
 }//构造数字三角形 
 cout << MaxSum(n) << endl;
 int k = 1;
 for (int i = k; i <= n; i++)
 { 
 cout << a[i][k] << " ";
 if (max[i + 1][k + 1] + a[i][k] > max[i + 1][k] + a[i][k])
 { 
 k = k + 1;
 }
 }//打印路径
 return 0;
} 
四.证明数字三角形的最优子结构性质。
证:
原问题:MAX[i,j] 最优解 L[n]
子问题:MAX[i+1,j+1] 最优解 L’[n]
反证法:设L’[n] 不为子问题的最优解,令M’[n]为子问题的最优解
则M’[n]<L’[n] 所以 M’[n]+L[n-1]<L’[n]+L[n-1]=L[n]L[n]为原问题的最优解相矛盾,即证! 五、答案显示 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 30 7 3 8 7 5 

六、算法分析(T(n)和S(n))
本程序为递推型动归程序,由底向上递推,除最后一行外,每一行的每个点
最顶部即为所求。其三角形的数字总和为 n(n + 1)/2,算法的时间复杂度 T(n) = O(n^2),空间复杂度与n成线性比例关系,即其空间复杂度 S(n) = O(n);
七、课程设计总结
通过本次课程设计和实际操作,对于动态规划有了更好的的理解,尤其是对最优子结构的认识更加深刻,从中学到了许多新的编程思想。知道了如何更好地设计算法很大的提高了编程效率。
在解决本次题目—数字三角形中出现了一些因为粗心而出现的问题,经过小组讨论和一反调试最终将所有问题解决。实验的成功离不开小组三人的合作以及老师的指导,本次试验不仅在算法问题上收获颇丰,并且因为小组三人的通力协作,加深了对此次问题的理解和学习。

    原文作者:菜鸟·博客
    原文地址: https://blog.csdn.net/songjiasheng1314/article/details/80990733
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞