《三国演义》有一段很精彩的描写,说的是曹操煮酒论英雄。曹操剪除吕布之后,权势日增,挟天子以令诸侯。刘备新败,兵微将寡,无尺寸之地可以安身立命。只好暂时依附曹操。为了避免曹操猜疑,刘备不得不韬光养晦,每日灌园浇菜,装做已经胸无大志的样子。曹操为了摸清刘备的底,于是青梅煮酒,邀刘备共饮,酒至半酣,曹操忽然请问刘备,谁是当世的英雄。刘备当然也清楚曹操的用心,便故意装痴卖傻地把各路诸侯一个个地列举出来,但都被曹操一个个地否定了。最后,叱咤风云的英雄人物,只剩下曹操与刘备了。这时,曹操才得意洋洋地宣布:“今天下英雄,唯使君与操耳!”
刘备和曹操在这里使用了“穷举法”。
所谓“穷举法”,就是在讨论一个问题时,把所有可能的情况都列举出来,一个不重,一个不漏,然后对各种可能情况逐一分析,去掉不合条件的,留下符合条件的,最后作出结论。用穷举法来论证问题,看起来有些原始,有些笨拙,但却是逻辑堆证中不可或缺的方法。
还是这个曹操,大概由于生前树敌太多,恐怕死后有人掘其坟墓,便在漳河一带造了72个疑冢。这样一来,人们就难以找到曹操的墓了。但后人有诗曰:“尽掘七十二疑冢,必有一冢葬君尸。”诗人提出了一个办法:对72座疑冢,一个一个地掘下去,只要曹操的确是埋在72冢之中,曹操的尸骨就总会被挖出来。这又是用的穷举法。
使用穷举法,要做到一个不重,一个不漏,特别是要一个不漏。重则造成浪费,漏则可能导致错误。《聊斋志异》中有一则《曹操冢》,那篇小说中说曹操的墓竟在72冢之外,那位诗人的穷举法原来有遗漏,终于让曹操避免了被“掘墓鞭尸”的厄运。老谋深算的曹操,再一次妙用了穷举法的原理。
在许多以侦破为题材的影视或小说中,常常使用穷举法。某处突然发生了疑案,侦破人员便将所有可能的犯罪嫌疑人一一列举出来,然后逐个调查取证,逐个排除,最后视线集中到一两个人身上,终于找出了真正的犯罪分子。看多了,也许觉得千篇一律,单调乏味。但是,侦破工作确实是离不开穷举法的。
穷举法在数学中也是一种司空见惯,屡建奇功的方法。通过数学问题训练人的穷举思维,也有奇特的功效,是别的方法所难于替代的。
也许正因为侦破工作离不开穷举法。英国著名侦探小说作家柯南道尔在他的名著《福尔摩斯历险记》中,特意安排了一段情节,让福尔摩斯用穷举法去解一道数学难题。从解题的过程中显示出了福尔摩斯运用穷举法的能力,这大概也是他能成为一个著名侦探的必备条件之一吧。
福尔摩斯有一天到他的朋友华生医生家去作客,听到外面庭院里一大群孩子的喧闹声,便问华生医生有几个孩子。华生医生并没有正面回答客人的问题,却说出了一道颇有难度的数学题。
下面是主客之间的对话:
主人:“那些孩子不完全是我的,那是四家人的孩子。我的孩子最多,弟弟的孩子其次,妹妹的更其次,叔叔的孩子最少。虽然他们还不够按9人一行排成两行,但却可以把整个院子闹得乱七八糟,天翻地覆。不过,说来也巧,如果把我们四家的孩子数乘起来,其积正好等于我家的门牌号数。至于我家的门牌号数,您是知道的哪!”
客人:“哈哈!我过去在学校里也学过数学的呀!让我试试把每家的孩子算出来吧!(稍为思索了一会)但对于这个问题,已给的信息还不能得出结论,请您告诉我,您叔叔的孩子是一个呢?还是不止一个?”
华生医生回答了这个问题之后,福尔摩斯马上准确地说出了各家孩子的数目。
大侦探是怎样算出各家孩子数的呢?当然离不开穷举法。
现在你并不知道门牌号数,也不知道叔叔的孩子数,能根据上文提供的信息,用穷举法算出各家的孩子数吗?让我们来分析一下:假设医生、弟弟、妹妹、叔叔的孩子数依次为a,b,c,d。那么,根据华生医生向福尔摩斯提供的信息,应有a>b>c>d(1)
a+b+c+d<18(2)
abcd=n(n为门牌号数)(3)
问题就是要求同时满足条件(1)(2)(3)的正整数解。
我们可以用穷举法列出满足条件(1)与(2)的所有四元数组(a,b,c,d)逐一分析,最后找出答案。不过这种四元数组有39种之多,逐一列举将不胜其烦。但若我们善于使用“同中求异”与“异中求同”的思维方法,则可较简单地解决。
首先注意,叔叔的孩子数d只能为1或2,因为若d≥3,则由条件(1),将有c≥4,b≥5,a≥6。从而a+b+c+d≥6+5+4+3=18,与条件(2)矛盾。类似地可以推出,医生的孩子数a<12。
第一步同中求异:对于任何一组可能的(a,b,c,d),都有a+b+c+d<18,这是同;但它们的乘积abcd(d=1或2)却不完全相同,这是异。
第二步异中求同:在两种乘积abcd(d=1)和abcd(d=2)中,一定有相同的。不然的话,由于福尔摩斯已经知道门牌号数n,如果在这两种乘积中只有一种乘积中有使abcd=n的,他就会知道叔叔的孩子数是1个还是2个。现在既然福尔摩斯还要向主人询问叔叔的孩子数,可见,无论是d=1或d=2时,都可使abcd的积等于门牌号数。我们必须找出这些相同的数组,这就要异中求同。
第三步再同中求异。假设我们找到了两组相同的乘职abc×1=a'b'c'×2=n,即2a'b'c'=abc。于是。a',b,'c',2这4个数可以看成是这样得来的:abc中的b、c保持不变,a分解成2与e的乘积而得到的,其中的e≠b,e≠c,e≠2。例如1×3×5×8=2×3×4×5=120,2,3,4,5可看成是由1,3,5,8中的8分解为2×4(e=4)而得到的。要找出这种不同的表达式,又要同中求异。在a×b×c×1=a'×b'×c'×2=n的数组中,a必须为偶数。于是a应满足6≤a≤10。
第四步又异中求同。满足abcd=n的四元数组,如果a×b×c×1和a×b×c×2每种都有2组以上的话,福尔摩斯即使知道了d=1或d=2,仍无法判断各家的孩子数。现在他说已能判断出各家的孩子数了,可知两种乘积中,至少有一种只有一组等于n。不过,由于我们没有听到华生医生告诉福尔摩斯叔叔的孩子数是多少,如果a×b×c×1与a×b×c×2都恰好只有一种等于n的话,我们仍然无法得知各家的孩子数。只有一种情况例外:两种乘积中,有一种恰有一组等于n,另一种有两组以上等于n。因此,为了找出某种乘积是否有两组以上等于n。又要异中求同。
至此,我们还没有作任何具体的列举和计算,只是经过了反复的同中求异与异中求同的分析,下面只要很少几步的列举和计算就可以了。因为6≤a≤10,且a为偶数,a只有三种可能,我们从a的值入手进行穷举。
当a=6时,因为6=2×3,所以c≠2,c≠3即c≥4,只有一种可能的四元数组:1,4,5,6。它可变为2,3,4,5。
1×4×5×6=2×3×4×5=120
当d=8时,因为8=2×4,所以c≠2,C≠4,b≠4,也只有一种可能的四元数组,1,3,5,8。它可变为2,3,4,5。
1×3×5×8=2×3×4×5=120
当d=10时,因为10=2×5,可知c≠2,c≠5,最小的四元数组(1,3,4,10),其和也超过了17。所以没有符合条件的四元数组。
由于d=1的情况有2种,d=2的情况恰有一种,即可完全判断门牌号数为120,四家的孩子数分别为2,3,4,5。
至于聪明的福尔摩斯,因为他事先知道门牌号数为120,根本用不着这样来分析,他可以使用更简单的穷举法:因为120=22×3×4×5,当把120分解成4个互不相等的正整数a,b,c,d的积,且满足a+b+c+d≤17的可能情况只有三种:a=8,b=5,c=3,d=1
a=6,b=5,c=4,d=1
a=5,b=4,c=3,d=2
各家的孩子数必定是上面三种情况之一。如果叔叔的孩子数是1,福尔摩斯虽然才智过人,亦难以准确判断出各家的孩子数。好在事从人愿,叔叔的孩子数恰好为2,这就使福尔摩斯顺利地破了这一“疑案”。