算法第五章作业

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

算法第五章作业

张杰

20130713班

2013E8018661133

1.最大子段和问题:给定整数序列 n a a a ,,,21 ,求该序列形如∑=j i

k k a 的子段和

的最大值: ⎭

⎬⎫

⎩⎨⎧∑=≤≤≤j

i k k n j i a 1max ,0max

1) 已知一个简单算法如下:

int Maxsum(int n,int a,int& best i,int& bestj){ int sum = 0;

for (int i=1;i<=n;i++){ int suma = 0;

for (int j=i;j<=n;j++){ suma + = a[j]; if (suma > sum){ sum = suma; besti = i; bestj = j; } }

}

return sum;

}试分析该算法的时间复杂性。 2)

试用分治算法解最大子段和问题,并分析算法的时间复杂性。

3) 试说明最大子段和问题具有最优子结构性质,并设计一个动态规划算法解最大子段和问题。分析算法的时间复杂度。 (提示:令1()max

,1,2,

,j

k i j n

k i

b j a j n ≤≤≤===∑)

1) 该算法的时间复杂性为)(2n O

2) 分治算法:将所给的序列a[1:n]分为两段a [1:n/2]、a[n/2+1:n],分别求出这两段的最大子段和,则a[1:n]的最大子段和有三种可能: ①a[1:n]的最大子段和与a[1:n/2]的最大子段和相同; ②a[1:n]的最大子段和与a[n/2+1:n]的最大子段和相同; ③a[1:n]的最大子段和为两部分的字段和组成,即

j n j

i

l n i j

a a a a a

+++++=+⎥⎦

⎥⎢⎣⎢=⎥⎦

⎥⎢⎣⎢∑ 122;

int MaxSubSum ( int *a, int left , int right){ int sum =0; if( left==right)

sum = a[left] > 0? a[ left]:0 ; else {

int center = ( left + right) /2;

int leftsum =MaxSubSum ( a, left , center) ; int rightsum =MaxSubSum ( a, center +1, right) ; int left_sum =0;

for ( int i = center ; i >= left; i--){ left_sum + = a [ i ]; if( left_sum <0) left_sum=0; }

int right_sum =0;

for ( int i = center +1; i <= right ; i++){ right_sum + = a[ i]; if( right_sum <0) right_sum=0; }

sum = left_sum + right_sum; if ( sum < leftsum) sum = leftsum; if ( sum < rightsum) sum = rightsum;

} return sum;

}

int MaxSum2 (int n){ int a[];

return MaxSubSum ( a, 1, n) ;

}

该算法所需的计算时间T(n)满足典型的分治算法递归分式 T(n)=2T(n/2)+O(n),分治算法的时间复杂度为O(nlogn) 3) 设}{max )(1∑=≤≤=j

i k k j

i a j b ,即

},,,,max {)(11211j j j j j j j a a a a a a a a a j b +++++=---

那么问题的答案就在)}(,),2(),1(max{n b b b . 而对于b(j)和b(j-1),二者有如下关系

}

,)1(max {},}{max max {},}{max {}{max )(1

1

11

11

1j j j j j i

k k j i j j i j j i k k j

i k k j i a a j b a a a a a a a j b +-=+=+==∑∑∑-=-≤≤-≤≤-==≤≤

所以有最优子结构性质,动态规划的公式为.1},,)1(max {)(n j a a j b j b j j ≤≤+-=

int MaxSum (int* a ,int n ) {

int b[n]=0; int sum = 0; b[1]=a[1];

for( int i=2;i<=n;i++) { if( b[i-1] >0)

b[i] = b[i-1] + a [i];

else

b [i]= a [i];

if( b [i]> sum)

sum = b[i];

}

return sum; }

容易得到时间复杂度为O (n )

2. (双机调度问题)用两台处理机A 和B 处理n 个作业。设第i 个作业交给机器A 处理时所需要的时间是i a ,若由机器B 来处理,则所需要的时间是i b 。现在要求每个作业只能由一台机器处理,每台机器都不能同时处理两个作业。设计一个动态规划算法,使得这两台机器处理完这n 个作业的时间最短(从任何一台机器开工到最后一台机器停工的总的时间)。以下面的例子说明你的算法:

)4,3,11,4,8,3(),,,,,(),2,5,10,7,5,2(),,,,,(,6654321654321===b b b b b b a a a a a a n

解:设)(i T 为完成前i 个作业,系统所需的最短处理时间,]}[],[m ax {)(i s i s i T b a =

][i S a 表示在完成前i 个作业所需时间最少的策略下,分配到A 机器上处理的作业的时间,

][i S b 表示在完成前i 个作业所需时间最少的策略下,分配到B 机器上处理的作业的时间

得到)(i T 的递推公式}}]1[,]1[m in{),1(m ax {)(i b i a b i S a i S i T i T +-+--=, 其中]}[],[m ax {)(i s i s i T b a =。

直接的关系式即是,

且 且 ⎪⎩⎪⎨⎧->++<++->++<++-<++-=)

1()1()

1(},min{)1()(i T a S b S a S a S i T b S a S b S b S i T b S a S i T i T i a i b i a i

a i

b i a i b i b i b i a , 其中为了方便,]1[-=i S S a a ,]1[-=i S S b b

得到算法如下:

int minTime(int *a, int *b, int n) //a,b 为A,B 机器上处理作业所用时间数组 {

int sa=0; //sa 表示分配到A 机器上处理的作业的最短总时间 int sb=0; //sb 表示分配到B 机器上处理的作业的最短总时间 int T=0; //T 为最短总的处理时间 for(int i;i

if((sa+a[i]T)) //式(1)中的情况3 {

sa+=a[i]; T=sa;

}

else if((sb+b[i]T)) //式(1)中的情况2

{

sb+=b[i]; T=sb;

相关文档
最新文档