看这道题的算法都是其他语言实现的,写一个python版的:
埃及分数(50分)
题目内容:
在古埃及,人们使用单位分数的和(如
, a是自然数)表示一切分数。例如:
,但不允许加数中有相同的,例如
。对于一个分数
,表示方法有很多种,但是哪种最好呢?首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。如:
19/45=1/3 + 1/12 + 1/180
19/45=1/3 + 1/15 + 1/45
19/45=1/3 + 1/18 + 1/30
19/45=1/4 + 1/6 + 1/180
19/45=1/5 + 1/6 + 1/18
最优表示是最后一个。
编程求解 分数
(0<a<b)的最优表示
。
输入格式:
第一行 :一个整数 a
第二行:一个整数 b
输出格式:
从小到大输出找到的单位分数的分母,每行一个整数
输入样例:
19 45
输出样例:
5 6 18
原理就不多说了。核心思想就是迭代加深,从2开始逐渐增加分数个数。然后迭代分母逐渐增大,在dfs中疯狂剪枝。剪枝对分母的范围进行限定。最小可以取范围是b/a向下取整,最大可以取bx/a向上取整(x为剩余分母个数), 若分母取的比这个大,那么结果会小于a/b。
import math#埃及分数 解法2
from fractions import Fraction
def cal(frac,res,result,depth,start=0):#在分数个数为depth的情况下的结果
if frac==0:
if len(res)==depth:#达到深度+归零则入队
result.append(res)
return result
else:#未达到深度+归零则舍弃
return
else:
if len(res)==depth:#达到深度+未归零则剪枝
return #未达到深度+未归零则继续搜索
i=max(start+1,math.ceil(1/frac))#第一次循环取ceil(1/frac),以后取比上一个分母大的i值,及时剪枝
fcnew=Fraction(1,i)
while fcnew*(depth-len(res))>=frac:#分母从i开始循环计算分数,逐渐增大i
cal(frac-fcnew,res+[i],result,depth,i)
i+=1
fcnew=Fraction(1,i)
return result
def findMin(result):
minValue=10**5
for item in result:
if max(item)<minValue:
minValue=max(item)
minRes=item
return minRes
a,b=19,45
'''a=int(input())
b=int(input())'''
frac=Fraction(a,b)
maxDepth=5
depth=2
result=[]
while not result and depth<=maxDepth: #循环加深depth
result=cal(frac,[],[],depth)
depth+=1
result=findMin(result)
result.sort()
print(result)
运行结果:
[5, 6, 18]