算法分析与设计 实验三 最大子段和问题

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

昆明理工大学信息工程与自动化学院学生实验报告

( 201 — 201 学年 第 1 学期 )

课程名称:算法分析与设计 开课实验室: 年 月 日

一、上机目的及内容

1.上机内容

给定有n 个整数(可能有负整数)组成的序列(a 1,a 2,…,a n ),求改序列形如

∑=j

k k

a

1

的子段和的

最大值,当所有整数均为负整数时,其最大子段和为0。 2.上机目的

(1)复习数据结构课程的相关知识,实现课程间的平滑过渡; (2)掌握并应用算法的数学分析和后验分析方法;

(3)理解这样一个观点:不同的算法能够解决相同的问题,这些算法的解题思路不同,复杂程度不同,解题效率也不同。

二、实验原理及基本技术路线图(方框原理图或程序流程图)

(1)分别用穷举法、分治法和动态规划法设计最大子段和问题的算法; (2)对所设计的算法采用大O 符号进行时间复杂性分析;

(3)上机实现算法,并用计数法和计时法分别测算算法的运行时间; (4)通过分析对比,得出自己的结论。

穷举法是用一个二维数组将从i 到j 的和都记录下来,再比较各元素的大小,时间复杂性为O (n 2),分治法的设计思想是不断将问题为子问题,然后求解子问题,最后对解进行合并,时间复杂性为O(nlog n ),动态规划法的设计思想是将问题划分为若干个子问题,时间复杂度为O(n)。

分治法流程图:

穷举法流程图: 动态规划法流程图:

三、所用仪器、材料(设备名称、型号、规格等或使用软件)

1台PC 及VISUAL C++6.0软件

四、实验方法、步骤(或:程序代码或操作过程)

程序代码:

//穷举法

#include

void main()

{

int i,j,n;

int num[100],a[100],max;

printf("\t\t\t 最大子段和问题(穷举法)\n\n");

printf("请输入所要求最大字段和整数的个数:\n");

scanf("%d",&n);

printf("请分别输入这%d个整数的值:\n",n);

for(i=0;i

scanf("%d",&num[i]);

max=num[0];

for(i=1;i<=n;i++)

{

if(max

max=num[i];

}

a[1]=num[1];

for(i=1;i<=n;i++)

{

for(j=i+1;j<=n;j++)

{

a[i]+=num[j];

if(max

max=a[i];

}

}

if(max<0)

max=0;

printf("这%d个整数组成的序列的最大子段和是:%d\n",n,max); }

//分治法

#include

int MaxSum(int a[],int left,int right)

{

int sum=0;

if (left==right)

{

if (a[left]>0)

sum=a[left];

else

sum=0;

}

else{

int center=(left+right)/2;

int leftsum=MaxSum(a,left,center);

int rightsum=MaxSum(a,center+1,right);

int s1=0;

int lefts=0;

for(int i=center;i>=left;i--)

{

lefts+=a[i];

if(lefts>s1)

s1=lefts;

}

int s2=0;

int rights=0;

for(int j=center+1;j<=right;j++)

{

rights+=a[j];

if(rights>s2)

s2=rights;

}

sum=s1+s2;

if(sum

if(sum

}

return sum;

}

void main()

{

int n,a[100],m,maxsum;

printf("\t\t\t 最大子段和问题(分治法)\n\n");

printf("请输入所要求最大字段和整数的个数:\n");

scanf("%d",&n);

printf("请分别输入这%d个整数的值:\n",n);

for(m=1;m<=n;m++)

scanf("%d",&a[m]);

maxsum=MaxSum(a,1,n);

printf("这%d个整数组成的序列的最大子段和是:%d\n",n,maxsum);}

//动态规划法

#include

void MaxSum(int n,int a[])

{

int sum=0;

int b=0;

for(int i=1;i<=n;i++)

{

if(b>0)

b+=a[i];

else

b=a[i];

if(b>sum)

sum=b;

}

printf("这%d个整数组成的序列的最大子段和是:%d\n",n,sum);

}

void main()

{

int n,a[100],m,maxsum;

printf("\t\t\t最大子段和问题(动态规划法)\n\n");

printf("请输入所要求最大字段和整数的个数:\n");

scanf("%d",&n);

printf("请分别输入这%d个整数的值:\n",n);

for(m=1;m<=n;m++)

scanf("%d",&a[m]);

MaxSum(n,a);

}

五、实验过程原始记录( 测试数据、图表、计算等)

程序运行截图:

相关文档
最新文档