算法设计与分析报告大作业
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法分析与设计大作业
班级:12信科
姓名:郭倩南
学号:1242155105
完成日期:2015-6-4
指导教师:陈平
序号选定题目所用算法设计技术1数字三角形问题动态规划
2集合划分问题分治法
3
回溯法
求子集问题
评分:
大作业报告
1、数字三角形问题
一、问题描述
对于给定的由n行数字组成的数字三角形,计算从三角形的底至顶的路径经过的数字和的最大值。如:7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
二、实验内容与实验步骤
实验内容:
输入数据的第1 行是数字三角形的行数n,1<=n<=100。接下来n行是数字三角形各行中的数字。所有数字在0..99之间
实验步骤:
1、首先证明该问题满足最优化原理
最优化原理:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。
2、建立动态规划函数
3、填表
三、实验环境
Window7系统,vc++6.0软件
四、问题分析
由观察数字三角形可知,从数字三角形的顶层出发,下一层选择向左还是向右取决于两个4层数字三角形的最大数字和,而对于第四层的决定取决于第三层的最大数字和,依次类推,可知该问题是多阶段决策最优化问题,并且划分出来的子问题是相互重叠的,所以该问题采用动态规划法解决
动态规划:与分治法相似,把问题分解按层次分成子问题,直到可以直接求解的子问题,然后一级一级地向上求解。
与分治法的出别在于:动态规划适用有许多重复子问题出现的问题,它保留已求出问题的解。
7
3 8 3 8
8 1 0 8 1 1 0
2 7 4 4 2 7 4 7 4 4
4 5 2 6 5 4 5 2 6 5 2 6 5
一个五层数字三角形子问题(1)子问题(2)
五、问题解决
(1)根据对问题的分析,写出解决办法。
1、证明:S,S1,S2,..Sn,t是从S到t的一条数字和最大的路径,从源点S开始,设从S到下一段的顶点S1已经求出,则问题转化为求从S1到t的数字和最大的路径,显然S1,S2,...Sn,t一定构成一条从S1到t的数字和最大值的路径,如若不然,设S1,r1,r2,....rq,t是一条数字和最大的路径,则S,S1,r1,r2,....rq,t 的路径经过数字和的最大值比S,S1,S2,...Sn,t的路径数字和更大,从而导致矛盾,所以数字三角形问题满足最优性原理。
2、动态规划函数:
a[i][j]+=a[i+1][j] 当a[i+1][j]>a[i+1][j+1] 时
a[i][j]+=a[i+1][j+1] 当a[i+1][j]<=a[i+1][j+1] 时
3、填表
(2)你在调试过程中发现了怎样的问题?又做了怎样的改进?
答:(a)在代码编译成功后,显示屏上无任何提示语,让人有点不知所措,感觉设计的不太人性化,于是在代码中又添加了一些提示语句,使其更容易理解和操作
(b)算法设计比较简单,运行结果没有显示路径,所以还有待研究
(3)描述你在进行实现时,主要的函数或操作内部的主要算法;分析这个算法的时、空复杂度
答:主要算法:
int func()
{
int i,j;
for(i=n-1;i>=1;i--)
for(j=1;j<=i;j++)
{
if(a[i+1][j]>a[i+1][j+1]) a[i][j]+=a[i+1][j];
else a[i][j]+=a[i+1][j+1];
}
return a[1][1];
}
该段代码是程序的核心部分,可以根据此代码进行填表。
算法复杂度:O(T(n)∈O(n^2))
六、实验结果总结
七、附录及源程序
#include
using namespace std;
const int M=100;
int n;
int a[M][M];
int func()
{
int i,j;
for(i=n-1;i>=1;i--)
for(j=1;j<=i;j++)
{
if(a[i+1][j]>a[i+1][j+1]) a[i][j]+=a[i+1][j];
else a[i][j]+=a[i+1][j+1];
}
return a[1][1];
}
int main()
{
int i,j,max;
cout<<"请输入行数:";
cin>>n;
cout<<"请输入数字三角形:\n";
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
cin>>a[i][j];
max=func();
cout<<"最大值为"< } 实验参考的资料 【1】C++面向对象程序设计清华大学出版社 【2】算法分析与设计(第二版)清华大学出版社 2、集合划分问题 一、问题描述 给定正整数n,计算出n个元素的集合{1,2,…,n}可以划分为多少个不同的非空子集。 二、实验内容与实验步骤 n个元素的集合{1,2,…,n}可以划分为若干非空子集。例如,当n=3时,集合{1,2,3,4}可以划分为5个不同的非空子集。 三、实验环境 Window7系统,vc++6.0软件