最大子序列和的总结

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

最大子序列和

第一种情况:可以一个不取

【问题描述】:最大子序列和也叫数列的连续最大和,顾名思义,就是在一个长度为n的数列{An}中,求i,j(1<=i<=j<=n),使得数列{An}中,第i个元素到第j个元素之间,所有元素的和最大。例如:-2, 11, -4, 13, -5, -2时答案为20(11 -4 13)

解法一穷举法:以前我想出了一种算法,具体做法是:取出所给序列的所有子序列求和,共分n组,第一组长度为1,有n个;第二组长度为2, 有n-1个;……,最后一组,长度为n,只有一个。比较这n(n+1)/2个序列的和,再将每组的最大值比较,从而得到最大值以及其上下标。

a1 a2 a n-1 a n

a1+a2 a2+a3 a n-1+a n

a1+a2+a3 a2+a3+a4 ......

...... ......

a1+a2......+a n-1 a2+a3......+a n

a1+a2......+a n-1 +a n

此算法比较直接,也容易写出代码,但其时间开销为O(n2),空间开销为O(n),效率不高。

解法二:动态规划求解,

1

2

F[i]:表示以元素i结尾的连续最大子序列的和

那么对于第i个元素来说,要形成连续的最大子序列,只和相邻的前一个元素有关。因为可以不取,所以如果元素a[i]连接到以元素i-1结尾的最大连续子序列f[i-1]后是负数(f[i-1]+a[i]<0);则宁可不取,这样最大连续子序列和为0。

动态方程:

f[i]:=max{0,f[I-1]+a[i]} (边界条件:f[0]=0;)

3、代码1:

for I:=1 to n do

if (f[I-1]+a[i])>0 then f[i]:=f[I-1]+a[i] else f[i]:=0;

max:=-maxlongint;

for i:=1 to n do if f[i]>max then max:=f[i];

程序代码二:迭代进行

best:=-maxlongint;

temp:=0;

for i:=1 to n do

begin

temp:=temp+a[i]);

if temp>best then best:=temp;

if temp<0 then temp:=0;

end;

注意:加粗的循环体部分的顺序万万不可颠倒!

第二种情况:一定要取一个。

1、解法一:动态规划求解,

2

3

F[i]:表示以元素i结尾的至少要取一个的连续最大子序列的和

那么对于第i个元素来说,有两种选择:

选择一:因至少要选一个,所以可单独选a[i],此时和为a[i];

选择二:把a[i]连接到第i-1个元素结尾的最大连续子序列后。此时和为f[i-1]+a[i];

两种情况选较大者。

所以动态方程:

f[i]:=max{a[i],f[I-1]+a[i]} (边界条件:f[1]=a[1];)

4、代码:

F[1]:=a[1];

for I:=2 to n do

if (f[I-1]+a[i])>a[i] then f[i]:=f[I-1]+a[i] else f[i]:=a[i]; max:=-maxlongint;

for i:=1 to n do if f[i]>max then max:=f[i];

第三种情况:至少要取两个。

1、解法一:动态规划求解,

选择一:取长度为2:9-2=7;

选择二:把元素a[4]连接到元素a[3]结尾的后面。F[3]+a[4]=13-2

两者最较大者。

3、动态规划方程为:

F[i]:表示以元素i结尾的至少要取两个的连续最大子序列的和

那么对于第i个元素来说,有两种选择:

选择一:因至少要选两个,所以和为a[i-1]+a[i];

选择二:把a[i]连接到a[i-1]元素结尾的长度至少为2的最大连续子序列后。此时和为f[i-1]+a[i];

两种情况选较大者。

所以动态方程:

f[i]:=max{a[i-1]+a[i],f[I-1]+a[i]}(i>=3)

(边界条件:f[1]=a[1];f[2]=a[1]+a[2])

5、代码:

F[1]:=a[1]; f[2]:=a[1]+a[2];

for I:=3 to n do

if (f[I-1]+a[i])>a[i-1]+a[i] then f[i]:=f[I-1]+a[i]

else f[i]:=a[i-1]+a[i];

max:=-maxlongint;

for i:=2 to n do if f[i]>max then max:=f[i];

其它情况:

如2014年衢州市竞赛的转型,把相应的内容扩展到矩阵中而已。

5、求M子段和的最值。

问题描述:在一个长度为n的数列{An}中,求m个连续子序列,使得这m个连续子序列的和最大,且m个子序列无公共元素。特别地,若一子段的数全为负,则这个子段的和为0。(若两子段x[i..j]与y[i’..j’]不相交,则他们的关系是I<=j

输入:

第一行:n, m(1<=n<=100 1<=m<=10,m<=n) n表示数列中有多少数。

第二行:n个数每个数的绝对值<=1000

Sample Input

5 2

-5 9 -5 11 20

相关文档
最新文档