问题引入
今天的主题是迭代加深搜索,著名的埃及分数问题(古埃及的智慧。。哈哈)。
我们首先来看问题:
给出一个分数,由分子a 和分母b 构成,现在要你分解成一系列互不相同的单位分数(形如:1/a,即分子为1),要求:分解成的单位分数数量越少越好,如果数量一样,最小的那个单位分数越大越好。
如:
19/45 = 1/3 + 1/12 + 1/180;
19/45 = 1/5 + 1/6 + 1/18;
以上两种分解方法都要3个单位分数,但下面一个的最小单位分数1/18比上一个1/180大,所以第二个更优。
更多例子:
分析
我们如何解决在这个问题呢。首先我们当然会想到枚举分母,可是这可是自然数,根本不可能枚举完所有的情况,还有,相加的个数也枚举不完,完全可以1000个10000个相加甚至更多,所以,普通的搜索根本就束手无策。
我们再思考一下,很明显广搜是死定了(一层不可能搜完),那么改进后的深度搜索说不定可以加上一定的条件来解决这个难题。首先,深搜的深度是1~无穷,那我们就得对其进行优化,每一个分母,都有选中和不选中两种状态,如果选中,那么就减去这个分数,没有就跳过,但是上限究竟在哪呢。我们不妨继续看看题目,题目中特意提到了单位分数数量越少越好,那么,既然多组答案的优先级是由单位分数的个数首先决定,我们和不从2个单位开始,慢慢地放开限制,这次搜两个的,下次搜三个的,下下次搜四个的,ok,看似难办的个数问题就被我们解决了
接下来就是枚举分母的问题了,我们试图从分数的规则去找规律进行剪枝,如果我们无法高效地剪枝耗费的时间仍然会很大。我们可以发现这么一些规律:
1.后面数字的分母一定比前面数字大(不能相同,题目明显指出互不相同)
2.如果假设接下来的分母大小为x,后面的所有数字(总共有几个数字是由上文中枚举个数确定的)的分母都与接下来的分母相等都为x(虽然违反提议,但是你可以把这一步看成是数学课上数列的放缩法),但加起来却没有a/b大,那么我们后面的枚举都没有意义了(再怎么枚举也到不了a/b),所以,这种情况我们就可以剪枝了。
总的来说,我们的大方向就是迭代枚举个数,慢慢地从两个,三个,四个放宽,然后,在具体每一种个数的情况下,我们再去用上文的条件来剪枝,最终我们可以得到理想的答案。
代码实现
1 |
|
好,埃及分数的问题也解决完了,下一篇见。