第一章作业1.证明下列Ο、Ω和Θ的性质1)f=Ο(g)当且仅当g=Ω(f)证明:充分性。
若f=Ο(g),则必然存在常数c1>0和n0,使得∀n≥n0,有f≤c1*g(n)。
由于c1≠0,故g(n) ≥ 1/ c1 *f(n),故g=Ω(f)。
必要性。
同理,若g=Ω(f),则必然存在c2>0和n0,使得∀n≥n0,有g(n) ≥ c2 *f(n).由于c2≠0,故f(n) ≤ 1/ c2*f(n),故f=Ο(g)。
2)若f=Θ(g)则g=Θ(f)证明:若f=Θ(g),则必然存在常数c1>0,c2>0和n0,使得∀n≥n0,有c1*g(n) ≤f(n) ≤ c2*g(n)。
由于c1≠0,c2≠0,f(n) ≥c1*g(n)可得g(n) ≤ 1/c1*f(n),同时,f(n) ≤c2*g(n),有g(n) ≥ 1/c2*f(n),即1/c2*f(n) ≤g(n) ≤ 1/c1*f(n),故g=Θ(f)。
3)Ο(f+g)= Ο(max(f,g)),对于Ω和Θ同样成立。
证明:设F(n)= Ο(f+g),则存在c1>0,和n1,使得∀n≥n1,有F(n) ≤ c1 (f(n)+g(n))= c1 f(n) + c1g(n)≤ c1*max{f,g}+ c1*max{f,g}=2 c1*max{f,g}所以,F(n)=Ο(max(f,g)),即Ο(f+g)= Ο(max(f,g))对于Ω和Θ同理证明可以成立。
4)log(n!)= Θ(nlogn)证明:∙由于log(n!)=∑=n i i 1log ≤∑=ni n 1log =nlogn ,所以可得log(n!)= Ο(nlogn)。
∙由于对所有的偶数n 有,log(n!)= ∑=n i i 1log ≥∑=n n i i 2/log ≥∑=nn i n 2/2/log ≥(n/2)log(n/2)=(nlogn)/2-n/2。
当n ≥4,(nlogn)/2-n/2≥(nlogn)/4,故可得∀n ≥4,log(n!) ≥(nlogn)/4,即log(n!)= Ω(nlogn)。
综合以上两点可得log(n!)= Θ(nlogn)2. 设计一个算法,求给定n 个元素的第二大元素,并给出算法在最坏情况下使用的比较次数。
(复杂度至多为2n-3)算法:V oid findsecond(ElemType A[]){for (i=2; i<=n;i++)if (A[1]<A[i]){temp=A[1];A[1]=A[i];A[i]=temp;}for (i=3; i<=n;i++)if (A[2]<A[i]){temp=A[1];A[1]=A[i];A[i]=temp;}return A[2];}该算法使用的比较次数为:2n-33.设计一个算法,求给定n个元素的最大和最小元素。
(要求算法的复杂度至多为1.5n)算法:void Maxmin2(A;l,r;int x;int y);{if (l=r) { x=A[l]; y=A[r]; return;}if (r-l=1){ if (A[l]<A[r]) { x=A[l]; y=A[r];}else { x=A[r]; y=A[l];}return;}else { mid:=(l+r) div 2;Maxmin2(A,l,mid,x1,y1);Maxmin2(A,mid+1,r,x2,y2);x=min(x1,x2); y=max(y1,y2); }}该算法使用的比较次数为:1.5n-24.给定多项式p(x)=a n x n+ a n-1x n-1+…+a1x+a0,假设使用以下方法求解:p=a0;xpower=1;for (i=1; i<=n; i++){ xpower=x * xpower;p=p+a i * xpower;}求(1)该算法最坏情况下使用的加法和乘法分别为多少次?(2)能不能对算法的性能进行提高?解:(1)该算法最坏情况下使用的加法n次,乘法2n次(2)改进的算法为:float Horner(A, float x){p=A[n+1];for (j=1; j<=n; j++)p=x*p+A[n-j];return p;}该算法中使用加法n次,乘法n次第二章1.求解下列递推关系:1)当n≥1时,f(n)=3f(n-1);f(0)=5解:f(n)=3f(n-1)=32f(n-2)=…=3n f(n-n)= 3n *5=5*3n2) 当n≥2时,f(n)=5f(n-1)-6f(n-2);f(0)=1;f(1)=0解:该递推关系的特征方程为:x2-5x+6=0特征根为:r1=2;r2=3故f(n)=c1*2n+c2*3n有f(0)= c1*20+c2*30== c1+c2=1 且f(1)= c1*21+c2*31== 2c1+c32=0 可得c1 =3,c2=-2故f(n)=3*2n-2*3n3) 当n≥1时,f(n)=f(n-1)+n2;f(0)=0解:f(n)= f(n-1)+n2= f(n-2)+ (n-1)2+n2=….= f(0)+12+22+…+ (n-1)2+n2=12+22+…+ (n-1)2+n2=1/6 n(n+1)(2n+1)4) 当n≥1时,f(n)=2f(n-1)+n2;f(0)=1解:设f(n)=2n f’(n),且f’(0)= f(0)=1则2n f’(n)=2*(2n-1f’(n -1))+ n 2即f’(n)= f’(n -1)+n n 22 = f’(0)+∑=n i i i 122 =1+∑=n i ii 122所以f(n)= 2n *(1+∑=n i ii 122)=2n *(10-n n 26+)=10*2n -(n+6) 5) 当n ≥1时,f(n)=nf(n-1)+1; f(0)=1解:f(n)=n!*( f’(0)+ ∑=ni i 1!1) = n!*( 1+ ∑=ni i 1!1)2.求解下面的递推式:当n ≥2时,f(n)=4f(n/2)+n ; f(1)=1。
假设n 为2的幂,用直接展开法求解递推式。
解:令k n 2=f(n)=4f(n/2)+n=n n n f ++)2)2(4(*42 =n n n f ++2)2(422 =n n n n f +++22)2(4233 =….=n n n n f k k k ++++-22)2(41 =n f k k )122()1(41++++-=n n k )12(2-+=n n -223.求解下面的递推式:当n ≥2时,f(n)=9f(n/3)+n 2; f(1)=1。
假设n 为3的幂,用直接展开法求解递推式。
解:令k n 3= f(n) =2)3(9n nf +=222))3()3(9(9n n n f ++=2222)3(9n n n f ++=22233)3(9n n n nf +++=….=2)3(9kn nf k k +=n n n 322log +4. 法求解递推式的上界:当n ≥4时,n n f n f n f +⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢=)43()4()(;当n<4时,f(n)=4。
解: 由于递推式为44)43()4(4)(≥<⎪⎩⎪⎨⎧+⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢=n n n n f n f n f 这里14341=+ 故作猜想n nf n f +=)2(2)(的解为:n n n n f 4log )(+=故对原递推式做猜想n n cn n f 4log )(+≤ 由于n n f n f n f +⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢=)43()4()(n n n n c n n n c +⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢+⎥⎦⎥⎢⎣⎢⎥⎦⎥⎢⎣⎢≤43443log 43444log 4n nn n c n n n c ++++≤43443log 43444log 4=n n cn n cn 5)43log (log 43)4log (log 41+++-n cn n cn 5)3log 432(log +--=若使f(n)满足上界为n n cn 4log +则必有n n cn n cn n cn 4log 5)3log 432(log +≤+-- 即0)3log 432(≤+--n cn 所以23.13log 4321=-≥c故n n n n f 4log 23.1)(+≤,即上界为n n n 4log 23.1+4. 设计算法,求解问题:有一楼梯共M 级,刚开始时你再第一级,若每次只能跨上一级或二级,要走上第M 级,共有多少种走法?int fa(int m){int z;if (m==1) z=1;else if (m==2) z=2;、else z=fa(n-1)+fa(n-2);return z;}5.设计算法,一个射击运动员打靶,靶一共有10环,连开10枪打中90环的可能性有多少种?这道题的思路与字符串的组合很像,用递归解决。
一次射击有11种可能,命中1环至10环,或脱靶。
函数功能:求解number次打中sum环的种数函数参数: number为打靶次数,sum为需要命中的环数,result用来保存中间结果,total记录种数void ShootProblem_Solution(int number, int sum, vector<int> &result, int &total){I if(sum < 0 || number * 10 < sum)//加number * 10 < sum非常重要,它可以减少大量的递归,类似剪枝操作return;if(number == 1) //最后一枪{if(sum <= 10) //如果剩余环数小于10,只要最后一枪打sum环就可以了{for(unsigned i = 0; i < result.size(); i++)cout<<result[i]<<' ';cout<<sum<<endl;total++;return;}elsereturn;}for(unsigned i = 0; i <= 10; i++) //命中0-10环{result.push_back(i);ShootProblem_Solution(number-1, sum-i, result, total); //针对剩余环数递归求解result.pop_back();}}void ShootProblem(int number, int sum){int total = 0;vector<int> result;ShootProblem_Solution(number, sum, result, total);cout<<"total nums = "<<total<<endl;}int main(){ShootProblem(10, 90);return 0;}6.设计算法,求解猴子吃桃问题:有一群猴子摘来了一批桃子,猴王规定每天只准吃一半加一只(即第二天吃剩下的一半加一只,依此类推),第九天正好吃完,问猴子们摘来了多少桃子?思路:可假设有第十天,则第十天剩余的桃子数目为0,由此递推可得每一天剩余的桃子数目。