最大子段和的几种实现
我们知道最大子段和是指给出一组数字序列,在这个序列中有正有负,而最大的字段和就是指连续的几个数中,把这些数值加起来,求得最大的和,即为最大的子段和~ 今天,我们讨论的就是如何求得最大的子段和~这个实现,有几种算法,我们一一讲述~我们假设当求得的最大和为负数的时候,规定为0~
方法1:,我们讲述最简单的一种实现方式,也是最容易想到的就是用穷举法来实现~ 这个原理其实是很简单,就是一组一组的试,这样找到最大的值~这是很容易想到的~详见代码~
1 #include
2 #define maxn 1000
3 int main()
4 {
5 printf("the num of zi duan:\n");
6 int ziduan_len;
7 int a[maxn];
8 scanf("%d",&ziduan_len);
9 printf("please input the sequence of zi duan is :\n");
10 for(int i=0;imaxsum) 27 {
28 maxsum=sum; 29 besti=i; 30 bestj=k; 31 }
32
33 }
34 }
35 }
女包、名牌包、背包:www.naitiao.com|冬装新款、流行冬装、今年流行秋冬装:dongzhuang.qqxk.net
36 printf("choose from %d to %d can make the sum of sequence the
largest\n",besti,bestj);
37 printf("the largest sum is :%d \n",maxsum);
38 return 0;
39 }
这个程序很浅显,就不再多说了~
我们可以把以上代码优化一下,上面的代码的时间复杂度为O(n的三次方),稍微优化后,时间复杂度变成了O(n的平方)! 请看优化后的代码~
#include
#define maxn 1000
int main()
{
printf("the num of zi duan:\n");
int ziduan_len;
int a[maxn];
scanf("%d",&ziduan_len);
printf("please input the sequence of zi duan is :\n");
for(int i=0;imaxsum)
{
maxsum=sum;
besti=i;
bestj=k;
}
}
}
printf("choose from %d to %d can make the sum of sequence the largest\n",besti,bestj);
女包、名牌包、背包:www.naitiao.com|冬装新款、流行冬装、今年流行秋冬装:dongzhuang.qqxk.net
printf("the largest sum is :%d \n",maxsum);
return 0;
}
就是简单的去掉最后一个循环~
方法2 :我们用动态规划的思想来解决这个问题~ 这个问题从
数学
数学高考答题卡模板高考数学答题卡模板三年级数学混合运算测试卷数学作业设计案例新人教版八年级上数学教学计划
的角度上来讲,就是一个这样的问题:
就是求 max{ a[k]的和} k从i 到j 其中 1<=i<=j<=n 状态转移方程 b[j]=max{b[j-1]+a[j],a[j]}, 1<=j<=n
1 #include
2 #define maxn 1000
3 int main()
4 {
5 printf("the num of zi duan:\n");
6 int ziduan_len;
7 int a[maxn];
8 scanf("%d",&ziduan_len);
9 printf("please input the sequence of zi duan is :\n");
10 for(int i=0;i0)
21 {
22 b+=a[i];
23
24 }
25
26 else
27 b=a[i];
28 if(b>back_sum)
29 maxsum=b;
30
31 }
32 printf("the largest sum is :%d \n",maxsum);
33 return 0;
34 }
女包、名牌包、背包:www.naitiao.com|冬装新款、流行冬装、今年流行秋冬装:dongzhuang.qqxk.net
方法3:用分治算法来处理这个问题,将进一步降低时间复杂度至o(nlog(n)) 算法思想 :将 a[1:n]分成两段来求.整个子段的最大和无非有以下几种情况: 1.整个子段的最大和,是在a[1:n/2]中求得
2.整个子段的和是在a[n/2:n]中求得~
3.整个子段的最大和在中间求得,这个求最大和的过程中必定包含a[n/2]。
1 #include
2 #define maxn 1000
3 int maxsum(int *a,int left,int right)
4 {
5 int sum=0;
6 if(left==right)
7 sum=a[left]>0?a[left]:0;
8 else
9 {
10 int center =(left+right)/2; 11 int leftsum=maxsum(a,left,center);
12 int rightsum=maxsum(a,center+1,right);
13 int s1=0;
14 int lefts=0;
15 for(int i=center;i>=left;i--) 16 {
17 lefts+=a[i];
18 if(lefts>s1)
19 s1=lefts;
20 }
21 int s2=0;
22 int rights=0;
23 for(int i=center+1;i<=right;i++) 24 {
25 rights+=a[i];
26 if(rights>s2)
27 s2=rights; 28 }
29 sum=s1+s2;
30 if(sum
本文档为【最大子段和的几种实现】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑,
图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。