加法与乘法原理的联合使用
较难6加法与乘法原理一起用,搞定复杂计数问题
生活中,我们经常要数一数有多少种不同的选法、搭配方式或排列顺序。如果问题很简单,只用一个加法原理(分类相加)或乘法原理(分步相乘)就能算出来。但遇到复杂的情况,就需要两个原理手拉手一起上——先分类、再分步,或者先分步、再分类。学会了这个,你就能轻松解决很多有趣的计数问题,比如点餐选套餐、搭配衣服、统计比赛结果等等。
下面我们先从一个小例子说起,看看加法与乘法是怎样配合使用的。
? 分类与分步:两个原理的第一次合作
问题: 学校要选一名主持人,可以选“一男一女搭档”(两个人一起主持),也可以只选“一个男生”。主持人的备选名单里有3名男生和2名女生。问一共有多少种不同的选法?
第一步:先分类
我们把所有可能的选法分成两类:
- 第一类:一男一女搭档(两个人)
- 第二类:单独一个男生(一个人)
这两类不会重复,因为第一类是两个人,第二类是一个人,完全不同。所以总数就是第一类的数目 + 第二类的数目(加法原理)。
第二步:每一类内部再用乘法
- 第一类:要同时选一个男生和一个女生。这是两个步骤:先选男生(3种),再选女生(2种)。根据乘法原理,一共有
3 × 2 = 6种。 - 第二类:只选一个男生,就是直接从3个男生中选一个,有3种。
最后,总数 = 6 + 3 = 9 种。
我们用C++程序来模拟一下,让电脑帮我们数一数:
#include <iostream>
using namespace std;
int main() {
int total = 0; // 记录总选法数
// 第一类:一男一女(分两步:先选男生,再选女生)
for (int boy = 1; boy <= 3; boy++) { // 男生编号1~3
for (int girl = 1; girl <= 2; girl++) { // 女生编号1~2
total++; // 每找到一对就加1
}
}
// 第二类:只选一个男生(一步完成)
for (int boy = 1; boy <= 3; boy++) { // 每个男生单独算一种
total++; // 每个男生都是一种选法
}
cout << "一共有 " << total << " 种选法" << endl;
return 0;
}
运行结果输出 9,和我们算的一模一样。
? 更多生活中的例子
例1:搭配早餐
早餐店有3种面包(奶油、红豆、肉松)和2种饮料(牛奶、豆浆)。你想买一个面包和一杯饮料,或者只买一个面包。问有多少种不同的购买方案?
- 分类:
- 第一类:买面包+饮料(两个东西)
- 第二类:只买一个面包(一个东西)
- 第一类:选面包3种 × 选饮料2种 = 6种
- 第二类:选面包3种 = 3种
- 总数:6 + 3 = 9种
你会发现,这和主持人问题结构完全一样,只是换了物品名称。
例2:选择课外活动
学校有篮球、足球、乒乓球3种体育项目,还有合唱、绘画2种艺术项目。小明要选一个体育项目和一个艺术项目,或者只选一个体育项目。多少种选择?
- 分类同上,结果也是
3×2 + 3 = 9种。
例3:稍微变一变——选一男一女或选一男一女再加一个男生(三人组)
假如主持人要求:可以是“一男一女搭档”,也可以是“一男一女再加一个男生(共三人)”。备选名单里仍然是3男2女。问多少种选法?
- 第一类:一男一女 → 3×2 = 6种
- 第二类:三人组(一男一女 + 再加一个男生)。注意:这里“再加一个男生”是在已有的一男一女基础上再加人吗?实际上,三人组需要选1个男生和1个女生,然后再从剩下的男生里选一个?不对,因为三人组要包含两个男生和一个女生。所以更清楚的做法是:先分类为“两人组”和“三人组”,然后在三人组内部,需要选2个男生和1个女生。
三人组计数:选2个男生(组合问题)和1个女生。选2个男生有 C(3,2)=3 种(假设男生编号1,2,3,选哪两个?有3种:{1,2}、{1,3}、{2,3}),选1个女生有2种。所以三人组有 3×2 = 6 种。注意这里用到了乘法原理(先选男生组合,再选女生)。最后总数 = 6 + 6 = 12种。
重点:当分类内部需要分步时,就用乘法;当多个类别之间用加法。这个思路可以解决很多复杂问题。
⚠️ 新手容易犯的错误
-
分类重复或遗漏
比如上面主持人问题,如果把“一男一女”和“单独一个男生”分在一类,就会乱算。必须确保每一类之间互不重叠,且覆盖所有可能。 -
分步顺序搞错
在乘法原理中,每一步的选项数必须独立。比如先选男生再选女生,顺序不影响结果。但如果选人时不能重复选同一个,就要小心。比如从3个男生中选2个当正副班长,第一步选正班长3种,第二步选副班长2种(除去已选的人),这才是正确的乘法。 -
忘记分类
有些问题看起来能用乘法,但实际上需要先分类。比如“选一个主持人,可以是男生或女生”看起来是两步?不,这是分类:选男生或女生,每类内部再用乘法?其实这里直接加法:男生3种 + 女生2种 = 5种。如果你错误地用乘法:3×2=6,就多算了(因为不能同时选男和女)。 -
循环模拟时漏掉某些情况
用编程验证时,要确保循环覆盖所有情况。比如主持人问题,第一类用两层循环,第二类用一层循环,没有遗漏。
? 完整示例:用C++模拟更多变式
下面我们写一个完整程序,模拟“选一男一女搭档 或 选一男一女再加一个男生(三人组)”的情况,并统计结果。
#include <iostream>
using namespace std;
int main() {
int total = 0; // 总选法数
int boys = 3; // 男生人数
int girls = 2; // 女生人数
// 第一类:一男一女搭档
for (int boy = 1; boy <= boys; boy++) { // 遍历男生
for (int girl = 1; girl <= girls; girl++) { // 遍历女生
total++; // 每对算一种
}
}
// 第二类:三人组(两个男生 + 一个女生)
// 需要选两个不同的男生,所以用两层循环,但注意 (boy1,boy2) 和 (boy2,boy1) 算同一组
// 我们让 boy1 < boy2 来避免重复计数
for (int boy1 = 1; boy1 <= boys; boy1++) { // 第一个男生
for (int boy2 = boy1 + 1; boy2 <= boys; boy2++) { // 第二个男生,编号更大
for (int girl = 1; girl <= girls; girl++) { // 选一个女生
total++; // 每组三人算一种
}
}
}
cout << "一共有 " << total << " 种选法" << endl;
// 结果应该是 6 (两人组) + 3*2 = 6 (三人组) = 12
return 0;
}
运行这个程序,你就会得到12种。注意在枚举三人组时,我们用 boy1 < boy2 避免重复选取同一组男生(因为两个男生不分顺序)。这就是用循环模拟组合的方法。
? 相关知识点指引
- 加法原理和乘法原理的基本概念:如果还不熟悉,可以先复习基础。
- 排列与组合:当需要选多个不同的人或物品时,常常要用到组合数公式
C(n,m),这能让你不用循环也能快速算出结果。 - 容斥原理:当分类之间有重叠时,需要用到容斥原理来避免重复计算。
- 编程与数数:用循环模拟是验证计数结果的好方法,但要注意循环的写法要正确反映计数规则。
下次遇到复杂的计数问题,记得先问自己:“我该分成几类?每一类里又需要分几步?” 想清楚了,答案就离你不远了。
例题精讲
用数字0,1,2,3,4,5可以组成多少个无重复数字且个位是偶数的四位数?
用数字0,1,2,3,4可以组成多少个无重复数字且大于3000的四位数?
在解决计数问题时,如果一个问题可以分成若干互斥的类别,每类内部又需要分步完成,那么应该先分类再分步,即加法原理后接乘法原理。
下面的C++代码用于计算用数字0-5组成无重复数字且能被5整除的三位数的个数。请补全代码。\n\nint count = 0;\n// 个位为0\ncount += 5 * 4;\n// 个位为5\ncount += ___;下面的C++代码用于计算用数字1-9组成无重复数字且百位<十位<个位的三位数的个数。请补全循环内的代码。\n\nint count = 0;\nfor(int i=1;i<=9;i++){\n int n = 9 - i;\n count += ___; // 从大于i的数字中选两个递增排列\n}