加法原理与乘法原理——数数也有规律
中等2数数也有规律——加法原理和乘法原理
生活中,我们经常需要数一数有多少种不同的可能性。比如,周末去游乐场,妈妈让你选一个项目玩:你可以选择坐过山车或者旋转木马。过山车有 3 种颜色的车厢,旋转木马有 2 种颜色的马。如果你只能选一样,那么你一共有多少种选择?这里的“选一样”是“要么选过山车,要么选旋转木马”,两种类别互不重合,总数就是 3 + 2 = 5 种。这就是 加法原理。
再比如,你要先选一件上衣,再选一条裤子。衣柜里有 2 件上衣、3 条裤子。那么一共有多少种穿法?第一步选上衣有 2 种,第二步选裤子有 3 种,每一步的选择是连续的,总穿法就是 2 × 3 = 6 种。这就是 乘法原理。
这两个原理是计数的基本法则,几乎所有排列组合问题都建立在它们之上。下面我们详细讲解这两个原理,并用 C++ 代码来帮忙计算。
1. 加法原理:分类计数,各算各的
核心思想:做一件事有 n 类办法,每一类办法里又有若干种具体方法。只要各类办法之间 互不重叠(即任何两种办法不会同时发生),那么总的方法数就是各类方法数之和。
生活例子:
- 学校食堂午饭有 3 种面、4 种饭。如果你只选一种主食(要么面要么饭),那么选择一共有 3 + 4 = 7 种。
- 零花钱你打算买零食或者文具:超市里零食有 5 种,文具有 3 种。你只能买一样东西,那么有多少种购买可能?5 + 3 = 8 种。
- 周末你要去公园玩,可以走路、骑车、坐公交。走路有 2 条路线,骑车有 3 条路线,坐公交有 1 条路线(都是不同的路线)。那么去公园的不同方式总数是 2 + 3 + 1 = 6 种。
C++ 代码示例:
#include <iostream>
using namespace std;
int main() {
// 加法原理:选一样主食
int noodles = 3; // 面的种类数
int rice = 4; // 饭的种类数
int total_food = noodles + rice; // 总选择数
cout << "选一样主食的总数: " << total_food << endl;
// 加法原理:去公园的不同方式
int walk = 2; // 走路路线数
int bike = 3; // 骑车路线数
int bus = 1; // 公交路线数
int total_way = walk + bike + bus; // 总方式数
cout << "去公园的方式总数: " << total_way << endl;
return 0;
}
关键点:加法原理要求分类的“类别”之间没有重叠。如果一件事既可以属于第一类又可以属于第二类,那就不能简单相加(那会重复计算),需要用到“容斥原理”。
2. 乘法原理:分步计数,步步相乘
核心思想:做一件事需要 连续完成 n 个步骤,每个步骤有若干种方法,并且每个步骤的选择 相互独立(前一步不影响后一步的方法数),那么总方法数就是各步骤方法数的乘积。
生活例子:
- 你要搭配一套服装:上衣 2 件,裤子 3 条,鞋子 2 双。先选上衣,再选裤子,最后选鞋子,总搭配数 = 2 × 3 × 2 = 12 种。
- 考试题目分为选择题和填空题:选择题有 4 个选项,填空题有 5 个空(每个空填一个字母)。做题时先答选择题(4 种答案),再答填空题(5 种答案),总答案组合数 = 4 × 5 = 20 种。(注意:这里假设每道题只有一个正确答案,我们只是数可能的答案组合。)
- 你有一个密码锁,密码是 3 位数字(每位 0~9)。那么不同密码的数量是:第一位 10 种 × 第二位 10 种 × 第三位 10 种 = 1000 种。
C++ 代码示例:
#include <iostream>
using namespace std;
int main() {
// 乘法原理:穿衣搭配(上衣、裤子、鞋子)
int shirts = 2; // 上衣件数
int pants = 3; // 裤子条数
int shoes = 2; // 鞋子双数
int total_outfit = shirts * pants * shoes; // 总搭配数
cout << "穿衣搭配总数: " << total_outfit << endl;
// 乘法原理:3位数字密码
int digit = 10; // 每位数字有10种可能
int total_pwd = digit * digit * digit; // 总密码数
cout << "3位数字密码总数: " << total_pwd << endl;
return 0;
}
关键点:乘法原理的步骤必须是 分步完成,并且每一步的方法数互不影响。如果某一步的选择会改变其他步的方法数,那就不能用简单的乘法,需要用到条件计数(比如排列数)。
3. 加法与乘法的结合——更复杂的问题
实际问题中,经常需要同时用到加法和乘法。比如:你想选一套衣服,可以选上衣+裤子,或者连衣裙+外套。上衣有 2 件,裤子有 3 条,连衣裙有 1 条,外套有 2 件。那么总共有多少种穿法?
分析:有两种大类(上衣+裤子 或者 连衣裙+外套)。第一类(上衣+裤子)需要分两步:先选上衣(2种),再选裤子(3种),所以第一类有 2 × 3 = 6 种。第二类(连衣裙+外套)也需要分两步:先选连衣裙(1种),再选外套(2种),所以第二类有 1 × 2 = 2 种。两类互不重叠,总方法数 = 6 + 2 = 8 种。
C++ 代码示例:
#include <iostream>
using namespace std;
int main() {
// 结合例子:一套衣服的穿法
int shirts = 2; // 上衣数量
int pants = 3; // 裤子数量
int dress = 1; // 连衣裙数量
int jacket = 2; // 外套数量
// 第一类:上衣+裤子
int type1 = shirts * pants;
// 第二类:连衣裙+外套
int type2 = dress * jacket;
// 总穿法
int total = type1 + type2;
cout << "总穿法: " << total << endl;
return 0;
}
4. 新手容易犯的错误
- 混淆加法和乘法:看到“或者”就认为是加法,看到“并且”就认为是乘法,但关键看是“分类”还是“分步”。例如:“小明从家到学校可以坐地铁或公交车,地铁有 3 条线,公交车有 2 条线” → 加法。“先坐地铁再坐公交车(中间换乘)”则变成乘法,但这里换乘需要两步,且每一步独立。
- 忘记考虑步骤独立性:乘法原理中,如果前一步的选择会影响后一步的方法数,就不能直接乘。例如:从 10 本书中选 2 本不同的书(有顺序),第一本有 10 种,第二本只剩 9 种,所以总数为 10 × 9,而不是 10 × 10。这就是排列问题,不是简单的乘法原理——但本质还是分步,不过每一步的方法数在变化。
- 加法原理中类别有重叠:比如“选择吃水果或甜点”,水果有 5 种,甜点有 3 种,但有一种水果蛋糕既算水果也算甜点,那么总数就不是简单的 5+3=8,而要减去重叠的 1 种。初学者容易直接相加,导致重复计数。
- 忘记单位:数数时对象要一致。例如“买一支笔和一块橡皮”是两步,乘法;但“买一支笔或一块橡皮”是一步,加法。
5. 完整可运行的示例(含用户输入)
下面是一个综合例子:根据用户输入计算不同情况下的选择数。
#include <iostream>
using namespace std;
int main() {
cout << "===== 加法原理和乘法原理演示 =====" << endl << endl;
// 加法原理:选一样零食
cout << "【加法原理】你有两种零食可选:糖果或饼干。" << endl;
int candy = 4; // 糖果种类数
int cookie = 3; // 饼干种类数
int snack = candy + cookie;
cout << "选一样零食的总种类: " << snack << endl << endl;
// 乘法原理:搭配早餐
cout << "【乘法原理】早餐先选饮品,再选主食。" << endl;
int drinks = 3; // 饮品选择数(牛奶、豆浆、果汁)
int foods = 4; // 主食选择数(面包、粥、包子、蛋糕)
int breakfast = drinks * foods;
cout << "早餐搭配总数: " << breakfast << endl << endl;
// 结合例子:周末活动
cout << "【综合】周末你可以选择:在家看书(有5本不同的书),或者出去玩(先选地点再选交通)。" << endl;
int books = 5; // 在家看书的种数
int locations = 3; // 出去玩的地点数
int transport = 2; // 每种地点的交通方式数
int outing = locations * transport; // 出去玩的总方式
int weekend = books + outing; // 周末活动总方案
cout << "在家看书有 " << books << " 种,出去玩有 " << outing << " 种(地点×交通)。" << endl;
cout << "周末活动总数: " << weekend << endl << endl;
// 让用户自己输入计算
cout << "===== 你自己来试试!=====" << endl;
cout << "假设你去文具店:可以买笔或者本子。" << endl;
int pen, notebook;
cout << "输入笔的种类数: ";
cin >> pen;
cout << "输入本子的种类数: ";
cin >> notebook;
int stationery = pen + notebook;
cout << "选一样文具的总数: " << stationery << endl;
cout << "再假设你要配一套:先选文具盒,再选书包。" << endl;
int box, bag;
cout << "输入文具盒种类数: ";
cin >> box;
cout << "输入书包种类数: ";
cin >> bag;
int kit = box * bag;
cout << "书包+文具盒的搭配总数: " << kit << endl;
return 0;
}
运行示例(用户输入 2 和 3,然后 4 和 2):
===== 加法原理和乘法原理演示 =====
【加法原理】你有两种零食可选:糖果或饼干。
选一样零食的总种类: 7
【乘法原理】早餐先选饮品,再选主食。
早餐搭配总数: 12
【综合】周末活动...
在家看书有 5 种,出去玩有 6 种(地点×交通)。
周末活动总数: 11
===== 你自己来试试!=====
假设你去文具店:可以买笔或者本子。
输入笔的种类数: 2
输入本子的种类数: 3
选一样文具的总数: 5
再假设你要配一套:先选文具盒,再选书包。
输入文具盒种类数: 4
输入书包种类数: 2
书包+文具盒的搭配总数: 8
6. 相关指引
掌握了加法原理和乘法原理,下一步可以学习:
- 排列与组合 —— 当有顺序要求时(如选班干部)用排列;不考虑顺序时(如选小组组员)用组合。
- 容斥原理 —— 当两个类别有重叠时,用来正确计数。
- 递推与动态规划 —— 很多计数问题可以拆成小问题的加法或乘法,比如走楼梯、爬格子。
- 概率入门 —— 用计数原理求出所有可能结果,再求概率。
这两个原理是数学和编程竞赛中“数数”的基石,多做生活化的练习,你就能熟练运用啦!
例题精讲
小明有3件不同颜色的上衣和2条不同颜色的裤子。如果他想搭配一套衣服(一件上衣和一条裤子),一共有多少种不同的搭配方式?
从甲地到乙地有3条不同的公路,从乙地到丙地有2条不同的铁路,从甲地直接到丙地有4条不同的航线。那么从甲地到丙地共有多少种不同的走法?
加法原理适用于“分步完成”的事件计数,而乘法原理适用于“分类完成”的事件计数。
小明计划从家到学校,先步行到公交站(有3条路线可选),再乘公交车到学校(有4条线路可选)。下面程序计算了所有可能的路线总数,请将空缺代码补充完整。
#include <iostream>
using namespace std;
int main() {
int a = 3, b = 4;
cout << ___ << endl;
return 0;
}某餐厅提供3种主食和4种饮料。如果顾客想选择一种主食或一种饮料(只选一样),那么总共有多少种选择?请补全如下程序。
#include <iostream>
using namespace std;
int main() {
int staple = 3, drink = 4;
cout << ___ << endl;
return 0;
}