[万丈高楼平地起] —— 枚举算法

百鸡百钱问题

鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?

———— 《算经》

前提:100只鸡 + 100块钱,100块钱须全部用完。

设购买公鸡、母鸡、小鸡的数量分别为x、y、z,则题目可转化为三元二次方程组。

x + y + z = 100

5*x + 3*y + z/3 = 100

由题意可知x、y、z的范围分别为[0, 20]、[0, 33]、[0, 100]。

分析到这里,不难写出如下代码。

def solution():
    ans = []
    for x in range(20):
        for y in range(33):
            for z in range(100):
                r1 = x + y + z == 100
                r2 = 5*x + 3*y + z/3 == 100
                if r1 and r2:
                    ans.append([x, y, z])
    return ans
# [[0, 25, 75], [3, 20, 77], [4, 18, 78], [7, 13, 80], [8, 11, 81], [11, 6, 83], [12, 4, 84]]

但是通过分析代码,不难发现在程序中我们没有必要进行三层循环。

将三元二次方程组转换为二元一次方程,由于z的范围较大,我们选择枚举x、y的值。

def solution():
    ans = []
    for x in range(20):
        for y in range(33):
            z = 100 - x - y
            if 5*x + 3*y + z/3 == 100:
                ans.append([x, y, z])
    return ans
# [[0, 25, 75], [3, 20, 77], [4, 18, 78], [7, 13, 80], [8, 11, 81], [11, 6, 83], [12, 4, 84]]

百鸡百钱问题到此就成功解决了,由上述分析我们可以得出枚举算法的流程。

  1. 建立数学模型,找出解空间。
  2. 思考是否需要枚举全局解空间?
  3. 选择合适的枚举顺序。

推荐阅读:

枚举 - OI Wiki

算法分享-枚举一种简单而又粗暴的算法让你明白为啥要用复杂密码-码农视野

你可能感兴趣的:(算法,枚举)