最近看一些数学方面的书,包括概率论、数理统计、随机过程、组合数学等,发现数学这个工具威力绝对是无穷的,若在编程中融入数学的一些思想,程序的运行效率会的得到前所未有的提升。遂将这些读书中的感想写成心得,起名曰“数学的力量”。
首先让我们从一个很简单的问题说起:
有方程a+b+c+d+e=20,求其非负整数解的个数。
题目很简单,首先想到的是使用回溯进行求解,遍历整个解空间数,对可行解进行计数,很容易就能得出答案。
解空间示意图如下,程序太简单所以就不多说了。
一共4层节点(前abcd确定了之后e也就确定了),每层最多16个,所以需要遍历的节点数最多也就是60000多个节点,正常情况下运行几个毫秒就运行完了,可以说还算是解决这个问题还不错的方法。(我画图的时候把0给忘了,算了,意思表达出来就行了)
好,接下来让我们使用数学的方法来解决这个问题。
首先这个问题等价成以下描述:
我有a,b,c,d,e五种商品若干,现在要从中选出20个商品,问共有多少种选法。
典型的多重集组合问题,直接用其公式C(n+r-1,n)也就是C(20+5-1,5)=C(24,5)即可算出。
完了,搞定!时空复杂度均是O(1),直接return 一个公式就行了,多么完美。
从这个例子我们可以看出数学的力量是多么的大,在编程中用好数学会让我们的编程水平再上一个档次。
ps:
关于多重集的概念以及其组合公式和推导,请参考相关组合数学书籍或者百度谷歌等,这里只是使用其公式而对多重集本身并不做过多的阐述。
有感兴趣的可以参考:
http://www.baidu.com/s?wd=%B6%E0%D6%D8%BC%AF%D7%E9%BA%CF&rsv_bp=0&rsv_spt=3&rsv_sug3=3&rsv_sug=0&rsv_sug1=2&rsv_sug4=426&inputT=4547