CC++ & Algorithm

乘法原理——一步一步来

困难3
语言版本:C++Python
概述:当一件事需要分几步完成,并且每一步都有不同的选择时,总的方法数就是各个步骤的选择数相乘。

分步计数的魔法——乘法原理详解

当你需要完成一件需要“先做这个,再做那个”的事情时,如何快速算出所有可能的方法数?比如搭配衣服、设计密码、规划路线……这里就藏着一个超好用的工具——乘法原理

什么是乘法原理?

乘法原理说的是:如果完成一件事需要分成 n 个步骤,并且第一步有 a 种方法,第二步有 b 种方法……那么完成这件事的总方法数就是 a × b × … 一直乘下去。

它与加法原理不同:加法原理是“要么这样,要么那样”(选择其中一个方案),而乘法原理是“先这样,再那样”(一步一步来,每一步都要做)。记住这个区别,后面就不容易搞混啦!

先从最简单的例子开始:穿衣服

想一想穿衣服的情景:你有 3 件上衣(T恤、衬衫、毛衣)和 2 条裤子(牛仔裤、运动裤)。想穿一套衣服出门,必须先选上衣,再选裤子,这样一共有几种搭配呢?

我们可以这么想:穿上衣有 3 种选法,然后每选一件上衣,都可以搭配 2 条不同的裤子。所以总搭配数就是 3 × 2 = 6 种。这就是乘法原理的直观体现。

Python 代码:计算上衣和裤子搭配总数

tops = ["T恤", "衬衫", "毛衣"]   # 3件上衣
pants = ["牛仔裤", "运动裤"]     # 2条裤子

# 乘法原理:将每一步的选择数相乘
total_outfits = len(tops) * len(pants)

print("一共有", total_outfits, "种搭配")
# 输出:一共有 6 种搭配

# 我们还可以用双重循环枚举出所有搭配(一步步来)
print("所有搭配如下:")
for top in tops:          # 第一步:选上衣
    for pant in pants:    # 第二步:选裤子
        print(top, "+", pant)

代码中,len(tops) 计算上衣数量,len(pants) 计算裤子数量,然后用乘法得到总搭配数。后面的双重循环正好体现了“先选上衣,再选裤子”的顺序。

生活中的其他例子

1. 点套餐

你去快餐店点套餐:先选主食(米饭、面条、馒头,3种),再选饮料(可乐、果汁、水,3种)。总共的套餐组合数是 3 × 3 = 9 种。

Python 代码:计算套餐种类

main_food = ["米饭", "面条", "馒头"]   # 3种主食
drinks = ["可乐", "果汁", "水"]         # 3种饮料

total_meals = len(main_food) * len(drinks)
print("一共可以搭配出", total_meals, "种套餐")
# 输出:一共可以搭配出 9 种套餐

2. 出行路线

从家到学校有 2 条路,从学校到图书馆有 3 条路。如果你要从家到图书馆(必须经过学校),那么路线总数是 2 × 3 = 6 种。每一步选一条路,合起来就是一条完整路线。

Python 代码:计算路线数

home_to_school = 2   # 家到学校的路
school_to_lib = 3    # 学校到图书馆的路

total_routes = home_to_school * school_to_lib
print("从家到图书馆共有", total_routes, "条路线")
# 输出:从家到图书馆共有 6 条路线

3. 设计一个简单的密码锁

密码锁由 2 个数字组成,第一位可以是 0~9 共 10 种,第二位也 10 种。那么总共有 10 × 10 = 100 种密码。

digit_choices = 10          # 每一位有10种数字(0-9)
total_pwd = digit_choices * digit_choices
print("2位数字密码有", total_pwd, "种")
# 输出:2位数字密码有 100 种

如果密码是 3 位数字呢?那就是 10 × 10 × 10 = 1000 种。你看,每多一步,方法数就乘一次。

乘法原理和加法原理的区别

  • 加法原理:做一件事有几种不同的方案,你只需要选其中一种。比如:早餐可以选择吃面包或吃饺子,有 2 种方案(面包1种、饺子1种,总共2种)。
  • 乘法原理:做一件事需要先做完一步,再做下一步,每一步都得完成。比如:先选择面包还是饺子(2种),再选择配牛奶还是豆浆(2种),总共有 2×2=4 种早餐搭配。

新手最容易犯的错误就是:把“或者”当成乘法,把“然后”当成加法。记住口诀:“或者”用加法,“然后”用乘法

常见错误提醒

  1. 步骤顺序搞反:乘法原理要求步骤有先后顺序,如果步骤可以互换,可能变成排列问题(那是高中才会学的)。但这里我们只按固定顺序。
  2. 漏掉步骤:比如从家到学校再到图书馆,你只算了从家到学校的路,忘了乘上从学校到图书馆的路,结果算成 2 种,那就不对了。
  3. 把“要么……要么……”当成乘法:如果问“今天穿红色上衣或蓝色上衣,共有几种选择?”这是加法原理,只有 2 种,不是乘法。

完整示例:计算一周的便当搭配

小明妈妈每周一到周五给他带便当。便当包含一盒主食和一种配菜。主食有 3 种选择:米饭、馒头、面条。配菜有 4 种选择:鸡腿、炒蛋、青菜、鱼。小明不想连续两天吃一样的主食和一样的配菜,请问一周(5天)有多少种不同的便当搭配方式?

注意:这里每周的便当可以重复,所以每一天都是独立选择,一天有 3×4 = 12 种搭配。一周有 5 天,但是每天的搭配可以选择任意一种,所以一周的总组合数不是乘法原理了(那是重复排列)。但我们只算一天:12 种。如果要算一周不重复的搭配,那是排列,这里先不深入。

我们先用代码计算一天的便当组合,并用双重循环枚举出来:

# 完整示例:便当搭配
staple = ["米饭", "馒头", "面条"]         # 3种主食
side_dish = ["鸡腿", "炒蛋", "青菜", "鱼"] # 4种配菜

one_day_options = len(staple) * len(side_dish)
print("一天有", one_day_options, "种便当")
# 输出:一天有 12 种便当

# 枚举所有便当组合
print("所有便当组合:")
for s in staple:
    for d in side_dish:
        print(s, "+", d)

# 如果你想知道一周5天,每天选一种(可重复),那么总的选择数是 12 的 5 次方,那不是乘法原理,而是幂次。
# 但这就是乘法原理的推广:重复做同一件事每次有12种,做5次,总结果数 = 12 * 12 * 12 * 12 * 12
# 这里只是提一下,免得混淆。
days_in_week = 5
total_weekly_combos = one_day_options ** days_in_week
print("一周5天(可重复)有", total_weekly_combos, "种不同的便当序列")
# 输出一个很大的数

相关知识点指引

学会了乘法原理,你就可以继续学习:

  • 加法原理:什么时候用加法,什么时候用乘法。
  • 排列与组合:遇到“选几个人排队”或“从一堆东西里挑几个”时,乘法原理是基础。
  • 树形图:用画树的方法一步步展示所有可能性,乘法原理正好对应树的分支数。

记住:遇到“先……再……”的分步问题,大胆用乘法!遇到“要么……要么……”的选择问题,用加法。多练练生活中的例子,乘法原理就会变成你的得力助手。

例题精讲

1单选题

从甲地到乙地有3条不同的公路,从乙地到丙地有2条不同的铁路,从甲地到丙地再经过乙地,共有多少种不同的走法?

A3+2=5种
B3×2=6种
C3×2×2=12种
D3+2+1=6种
2判断题

完成一项工作需要分两个步骤,第一步有4种方法,第二步有5种方法,那么完成这项工作共有4+5=9种方法。

3单选题

小明有3件不同颜色的上衣、4条不同款式的裤子和2双不同风格的鞋子,要搭配一套服装(上衣、裤子、鞋子各选一件/双),共有多少种不同的搭配?

A3+4+2=9种
B3×4×2=24种
C3×4+2=14种
D3×4×2×3=72种
4填空题
以下Python函数用于计算乘法原理的总方法数,函数接收一个包含各步骤方法数的列表steps。请补全代码。\ndef total_ways(steps):\n    total = 1\n    for s in steps:\n        total = total * ___\n    return total
5判断题

学校食堂供应3种主食、4种副食和2种汤品,每位同学选择一种主食、一种副食和一种汤品作为午餐,则午餐的组合方式共有3+4+2=9种。