分治法

       分治法与递归调用的不同之处在于分解问题的方式:一般的递归调用总是把问题分解为一个小问题和剩下的所有问题,而分治法会把问题分解为同等大小的子问题。时间复杂度比递归少

分治法具有以下3种构成要素:

  • 把问题分解为更小问题的分解过程。
  • 把各个小问题的答案合并为原问题答案的合并过程。
  • 不需要再分解而直接能够解答的最基本的问题。

示例:数列快速求和与矩阵快速乘方

fastSum(n) = 2 * fastSum(n/2) + n^2/4  (n是偶数)

fastSum(n) = fastSum(n-1) + n   (n为奇数)

int fastSum(int n) {
   if (n==1) return 1;
   if (n%2==1) return fastSum(n-1) + n;
   return 2*fastSum(n/2) + (n/2)*(n/2);
}

矩阵乘方,m非常大时,会耗费比较长的时间。O(n^3m)

,就可以减半

class SquareMatrix;
SquareMatrix identity(int n);
SquareMatrix pow(const SquareMatrix& A, int m) {
  if (m==0) return identity(A.size());
  if (m%2 > 0) return pow(A, m-1) * A;
  SquareMatrix half = pow(A, m/2);
  return half * half;
}

如果m是奇数,

示例:归并排序和快速排序

归并排序把数列从中间分开O(nlgn),而快排分成左小右大O(nlgn)。

示例:Karatsuba快速乘积算法

大整数相乘

练习题1:四叉树问题

把大量坐标数据压缩保存到内存空间。如用字符串的形式对黑白图像进行如下压缩。

  • 图像所有像素为黑色,结果为b。
  • 图像所有像素为白色,结果为w。
  • 不同颜色,一分为二,递归对四个小图像进行压缩,如xwwwb。

练习题2:切割篱笆

用长篱笆补短篱笆,保证切割出的面积最大的长方形。

第l个木板到第r个的长方形面积:(r-l+1) x min(h)

三种可能,求最大

  • 最大全部在左侧的子问题中
  • 最大全部在右侧的子问题中
  • 最大横跨左右两侧的子问题中

练习题3:粉丝见面会

a~d表示明星,0~5为粉丝,按顺序拥抱,不过男明星和男粉丝不拥抱,而是握手。计算所有成员同时和粉丝拥抱的情况。

O((N-M)M)时间复杂度,但是N和M可能是近20万,不能在限定时间内完成计算。

把它看成大数相乘就能快速解决

调换A的顺序,得到

int hugs(const string& members, const string& fans) {
   int N = member.size(), M=fans.size();
   vector<int> A(N), B(M);
   for (int i=0; i<N; i++)  A[i] = (members[i]=='M');
   for (int i=0; i<M; i++)  B[M-i-1] = (fans[i] == 'M');
   vector<int> C = karasuba(A, B);
   int allHugs = 0;
   for (int i=N-1; i<M; i++)
      if (C[i] == 0) 
          ++allHugs;
   return allHugs;
}

时间复杂度O(n^(lg3))

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值