做算法分析的目的通常是为了确定算法的时间效率。这是通过对算法的基础步骤执行次数进行计数来完成的。对于几乎一切算法问题来说,计数的结果都是随着问题的规模增长的。而考察到底增长得有多快,才是算法分析的主要目的。而谈到计数,毫不奇怪地,就涉及数学了。所以,我们就从一些重要的数学公式入手,它们在算法分析中发挥的作用真是不可小觑。
1 几个求和公式,兼论算法效率
关于史上最伟大的数学家之一Carl Friedrich Gauss(1777—1855),有一个众所周知但真实性可疑的故事,那就是当他10岁左右的时候,他的老师要求全班同学计算前100个正整数之和,即的值,他可能觉得这会花费这些学生相当一段时间。当然,老师没有想到这些学生中隐藏着一位数学高手。理所当然地,Carl只花了几分钟就得到了答案,方法是把全部数字分成50对,其中每一对都有着相同的和101:
![08149389ff9ea0361eac791dbe2b4584.png](https://img-blog.csdnimg.cn/img_convert/08149389ff9ea0361eac791dbe2b4584.png)
把这种思路推广到前个正整数,就得到了下面的公式:
![96509ccb96d26a099a3d1b1395d750cf.png](https://img-blog.csdnimg.cn/img_convert/96509ccb96d26a099a3d1b1395d750cf.png)
(1)作为练习,建议读者尝试求解谜题心算求和,其中就利用了本公式及其变形。
公式(1)在算法中有着无可取代的地位。还可以从它推导出若干其他的有用公式。比如,欲求前个正偶数的和,我们就可以得出:
![d6411e415ea3fc904cf72c1cc802cd80.png](https://img-blog.csdnimg.cn/img_convert/d6411e415ea3fc904cf72c1cc802cd80.png)
而前个正奇数的和,则这样推导:
![249f6f1d4b4a3b53d523ab2c2f1d1a8c.png](https://img-blog.csdnimg.cn/img_convert/249f6f1d4b4a3b53d523ab2c2f1d1a8c.png)
另一个非常重要的公式是2的各次方幂之和,我们在概论的前半部分已经用过:
![d69a5cb3289d943787ea459d771d9411.png](https://img-blog.csdnimg.cn/img_convert/d69a5cb3289d943787ea459d771d9411.png)
(2)现在我们来看第一道采用算法分析求解的谜题。
国际象棋的发明
据说,国际象棋游戏是很多个世纪以前由印度西北部的一位叫Shashi的贤人发明的。当Shashi将他的发明呈献给国王以后,国王爱不释手,并承诺给予这位发明人任何他想要的赏赐。Shashi说自己想要一些麦子,不过他是这么说的:在国际象棋棋盘的第1个格子里放1粒麦子,第2个格子里放2粒,第3个格子里放4粒,第4个格子里放8粒,依此类推,直至64个格子被放满为止。请问,这样的赏赐要求合理吗?
根据公式,Shashi要求的麦子总粒数等于:
![c8c33f3913b7d2604c45389c033780c4.png](https://img-blog.csdnimg.cn/img_convert/c8c33f3913b7d2604c45389c033780c4.png)
如果每一秒可以数一粒麦子的话,这个总数的数量需要花费5850亿年才能数完。这比已知地球年龄的100倍还要长。这个例子很好地说明了指数增长(exponential growth)有多么恐怖。显然,如果一个算法要求指数增长,那么除了极小的谜面以外,对于大多数情况它都没有实用性了。
如果Shashi要求的不是每格比前一格麦子粒数加倍,而是每格比前一格麦子粒数多两粒呢?这样,麦子的总粒数就等于: