Bài toán đếm và những sự lặp lại thú vị

Đăng ngày 18 tháng 3, 2026 ... views


Một điều mình nhận ra càng ngày càng rõ khi học toán rời rạc: những bài toán đếm tưởng chừng "đơn giản" lại là những cái bẫy dễ đánh lừa chúng ta nhất. Bạn nghĩ ra công thức, logic nghe hợp lý, rồi — sai. Không phải vì suy luận tệ, mà vì cách đếm bị lệch một chút.

Vấn đề cốt lõi: khi các phần tử lặp lại hoặc chồng chéo, cách đếm thông thường sẽ hỏng. Và các kỹ thuật để sửa — đếm phần bù, quy tắc thương, song ánh — lại là những ý tưởng dùng đi dùng lại nhiều nhất trong tổ hợp.

Trong bài này, mình muốn đi qua hành trình từ đếm chuỗi cơ bản đến hoán vị rồi anagram, vì nó là một hành trình từ "dễ quá" sang "khoan, sao lại sai?" rồi đến "ồ, hay thật."

Đếm "ít nhất một" bằng cách loại bỏ cái không muốn

Bài toán kinh điển: có bao nhiêu mật khẩu 8 ký tự (gồm chữ số, chữ thường, chữ hoa) chứa ít nhất một chữ hoa?

Lối suy nghĩ trực tiếp (chọn chữ, chọn chỗ, rồi điền nốt) nghe rất logic, thế nhưng việc đếm "ít nhất một" theo cách này lại là một mớ hỗn độn. Có cách gọn hơn nhiều.

Loading diagram...

Mẹo ở đây là đếm phần bù: đếm tất cả, rồi trừ đi những cái bạn không muốn.

Iˊt nhaˆˊt một chữ hoa=(10+26+26)8(10+26)8=628368\text{Ít nhất một chữ hoa} = (10 + 26 + 26)^8 - (10 + 26)^8 = 62^8 - 36^8

Vế đầu là tổng số mật khẩu 8 ký tự có thể có — với 62 ký tự cho mỗi vị trí, mỗi vị trí có thể là bất kỳ ký tự nào. Vế thứ hai là mật khẩu hoàn toàn không có chữ hoa — chỉ còn 36 ký tự. Trừ đi, bạn còn lại đúng những mật khẩu có ít nhất một chữ hoa.

Cách này hiệu quả vì "ít nhất một" rất khó đếm trực tiếp, nhưng "không có cái nào" thì dễ. Mọi thứ trở nên nhẹ nhàng hơn nhiều nhờ đếm phần bù.

Một phím chữ hoa phát sáng nổi bật giữa các phím chữ thường

📚 Lưu ý thực tế: NIST SP 800-63B-4 — chuẩn xác thực mà phần lớn hệ thống ở Mỹ đang theo — khuyến nghị mật khẩu tối thiểu 8 ký tự nhưng cố ý không bắt buộc các quy tắc về loại ký tự kiểu như "phải có chữ hoa". Hệ thống hiện đại đối chiếu mật khẩu với danh sách đã rò rỉ thay vì áp các ràng buộc về loại ký tự. Bài "ít nhất một X" ở đây là ví dụ giáo khoa, không phải chính sách bảo mật hiện hành.

Cái bẫy overcounting

Đây là đáp án sai mà trông cực kỳ thuyết phục:

26×8×62726 \times 8 \times 62^7

Logic: chọn 1 trong 26 chữ hoa, chọn 1 trong 8 vị trí, điền 7 vị trí còn lại tùy ý. Nghe hoàn hảo. Nhưng sai — vì đếm trùng.

Loading diagram...

Biểu thức này thực ra đếm bộ ba: (chữ hoa, vị trí, chuỗi 7 ký tự). Nhưng một mật khẩu có nhiều chữ hoa sẽ được tạo ra bởi nhiều bộ ba khác nhau. Chuỗi "FA65B227" có thể sinh ra từ việc chọn F ở vị trí 1 hoặc chọn A ở vị trí 4 — hai bộ ba khác nhau, cùng một chuỗi.

Các lựa chọn khác nhau "hội tụ" về cùng một kết quả — đây chính là đếm trùng

Dấu hiệu rõ ràng nhất: 26 × 8 × 62⁷ thực ra lớn hơn 62⁸ — tổng số mật khẩu. Không thể có nhiều mật khẩu "có ít nhất một chữ hoa" hơn tổng số mật khẩu được.

Nếu ánh xạ từ đối tượng bạn xây dựng đến tập hợp mong muốn không phải song ánh (bijection), bạn đang đếm trùng.

Nếu bạn thích cách dùng những lập luận đếm để giải quyết vấn đề thực tế, video Why this puzzle is impossible của 3Blue1Brown dùng một lập luận đếm chẵn lẻ rất tương tự để chứng minh một bài toán bàn cờ không có lời giải trừ khi kích thước bàn cờ là lũy thừa của 2 — minh họa đẹp cho việc đếm tinh tế giúp ta thấy cấu trúc mà lập luận thuần túy không thấy được.

Đang tải video…

Luyện tập: chuỗi 4 chữ số có ít nhất một số 0

Cùng ý tưởng, quy mô nhỏ hơn. Có bao nhiêu chuỗi 4 chữ số (0-9) chứa ít nhất một số 0?

Cách A: Cách sai

4 × 9³ = 2916. Phép tính này đếm những chuỗi có đúng một số 0 — chọn vị trí cho số 0 duy nhất, điền phần còn lại bằng chữ số khác 0. Công thức không sai, nhưng nó trả lời một câu hỏi khác — thiếu mất những chuỗi có 2, 3, hoặc 4 số 0.

Có nhiều đáp án đúng — và đó chính là phần thú vị.

Cách B: Đếm phần bù

10494=100006561=343910^4 - 9^4 = 10000 - 6561 = 3439

Tổng trừ đi chuỗi không có số 0. Gọn và rõ ràng.

Cách C: Đếm theo số lượng số 0

(41)93+(42)92+(43)91+(44)90\binom{4}{1} \cdot 9^3 + \binom{4}{2} \cdot 9^2 + \binom{4}{3} \cdot 9^1 + \binom{4}{4} \cdot 9^0
=4729+681+49+1=2916+486+36+1=3439= 4 \cdot 729 + 6 \cdot 81 + 4 \cdot 9 + 1 = 2916 + 486 + 36 + 1 = 3439

Đây dùng quy tắc tổng — chia tập hợp thành các nhóm không giao nhau (đúng 1 số 0, đúng 2, đúng 3, đúng 4) rồi cộng lại. Số 6 trong vế thứ hai là "chọn 2 từ 4" — số cách chọn 2 trong 4 vị trí để đặt số 0. Mình sẽ nói về tổ hợp chính thức ở bài sau, nhưng ý tưởng khá trực quan.

Cách D: Đếm theo vị trí số 0 đầu tiên

103+9102+9210+93=1000+900+810+729=343910^3 + 9 \cdot 10^2 + 9^2 \cdot 10 + 9^3 = 1000 + 900 + 810 + 729 = 3439

Nếu số 0 đầu tiên ở vị trí 1: 3 vị trí còn lại tùy ý (10³). Nếu ở vị trí 2: vị trí 1 phải khác 0 (9), phần còn lại tùy ý (10²). Tương tự cho các vị trí sau.

Loading diagram...

Ba cách đúng, ba biểu thức trông khác hẳn nhau, đều bằng 3.439. Cứ mỗi lần tìm ra một cách đếm mới cho cùng một tập hợp, bạn coi như đã "bỏ túi" được một đẳng thức toán học mà chẳng cần tốn công chứng minh. Chính logic đếm này là lời giải thích sinh động cho các công thức đại số.

Bốn hàng thẻ chữ số cho thấy số 0 đầu tiên xuất hiện ở các vị trí khác nhau

Từ chuỗi sang kẹo: song ánh như công cụ đếm

Đây là bài toán trông chẳng liên quan gì đến chuỗi: có bao nhiêu cách phân phát 10 viên kẹo khác nhau cho 4 trẻ khác nhau?

Mỗi viên kẹo là một loại khác nhau (Twix, Skittles, M&M's...). Bốn trẻ là bốn cá nhân khác nhau. Mỗi viên kẹo thuộc về đúng một trẻ. Bất kỳ trẻ nào cũng có thể nhận 0, 1, hoặc cả 10 viên.

Loading diagram...

Đáp án là 4¹⁰. Bí mật nằm ở song ánh (bijection) — chúng ta biến bài toán này thành một bài toán khác dễ hơn bằng cách thiết lập một liên kết 1-1 với thứ mà ta đã biết cách đếm.

Hãy nghĩ thế này: ta tạo ra một chuỗi dài 10 ký tự bằng bảng chữ cái {A, B, C, D}. Mỗi vị trí đại diện cho một viên kẹo. Ký tự ở vị trí đó cho biết đứa trẻ nào nhận kẹo đó.

Vị trí12345678910
KẹoTwixM&M'sSkittlesKit Kat3MuskSnickersMoundsAlmJoyReese'sHershey's
TrẻDDCADACCAA

Chuỗi "DDCADACCAA" ứng với đúng một cách phân phát: trẻ D nhận kẹo Twix, M&M's và Three Musketeers; trẻ C nhận Skittles, Mounds và Almond Joy; trẻ A nhận Kit Kat, Snickers, Reese's và Hershey's; còn trẻ B không nhận được gì. Mỗi cách phân phát ứng với đúng một chuỗi, và ngược lại. Đó là song ánh. Nên số cách phân phát bằng số chuỗi dài 10 trên bảng 4 ký tự: 4¹⁰ = 1,048,576.

Loading diagram...

Các viên kẹo phân biệt nối đến hộp ăn trưa và chuỗi phân phát tương ứng

Sức mạnh của song ánh là biến bài toán đếm khó hiểu thành bài toán quen thuộc. Chỉ cần chứng minh ánh xạ là một-một và toàn ánh, hai tập hợp phải cùng kích thước.

Hoán vị: khi không được lặp lại

Chuỗi trên bảng chữ cái cho phép lặp — bạn dùng cùng ký tự nhiều lần. Nhưng nếu mỗi ký tự chỉ được xuất hiện một lần?

Có bao nhiêu chuỗi 3 chữ cái từ {A, B, C, D, E} mà không lặp?

Loading diagram...

Mỗi khi điền xong một vị trí, số lượng ký tự bạn còn lại sẽ giảm đi một. Vị trí 1: có 5 cách chọn. Vị trí 2: 4 cách. Vị trí 3: 3 cách. Tổng: 5 × 4 × 3 = 60.

Đây gọi là hoán vị — cụ thể là r-hoán vị, với r là số vị trí cần điền.

Công thức tổng quát

Số cách sắp xếp r vật từ n vật phân biệt:

P(n,r)=n×(n1)×(n2)××(nr+1)P(n, r) = n \times (n-1) \times (n-2) \times \cdots \times (n-r+1)

Tích này có đúng r thừa số. Bạn cũng viết được dạng giai thừa:

P(n,r)=n!(nr)!P(n, r) = \frac{n!}{(n-r)!}

với n! = n × (n-1) × (n-2) × ... × 1.

Dạng giai thừa hoạt động vì mẫu (n-r)! triệt tiêu phần "đuôi" không cần. Ví dụ:

P(5,3)=5!(53)!=5!2!=1202=60P(5, 3) = \frac{5!}{(5-3)!} = \frac{5!}{2!} = \frac{120}{2} = 60

Thử thay đổi n và r ở đây:

📊

Hoán vị P(n, r)

Số cách sắp xếp r vật từ n vật phân biệt

Đầu vào
Kết quả
P(n, r) 720,00
n! 3.628.800,00

Khi r bằng n: sắp xếp tất cả

Khi sắp xếp toàn bộ n vật:

P(n,n)=n!P(n, n) = n!

Theo công thức:

P(n,n)=n!(nn)!=n!0!P(n, n) = \frac{n!}{(n-n)!} = \frac{n!}{0!}

Để ra kết quả n!, ta cần 0! = 1. Có hai lý do cho quy ước này:

  1. Đại số: làm công thức hoạt động — không cần trường hợp đặc biệt cho r = n.
  2. Tổ hợp: có bao nhiêu cách sắp xếp 0 vật? Đúng một cách — không làm gì cả. Chỉ có một cách sắp xếp rỗng.
Loading diagram...

Quy ước không phải tùy tiện. Nó là giá trị duy nhất khiến cả đại số lẫn tổ hợp nhất quán.

Một bộ bài xòe ra cho thấy số lựa chọn giảm dần khi các lá được sắp xếp

Anagram: khi chữ cái lặp lại

Hoán vị giả sử mọi vật đều khác nhau. Nhưng nếu một số giống hệt nhau thì sao? Đó là lúc anagram xuất hiện — sắp xếp lại một tập hợp có thể chứa phần tử trùng (multiset).

Tất cả khác nhau: MILES

Các chữ M, I, L, E, S đều khác nhau. Số anagram là 5! = 120.

Một vài trong số đó là từ tiếng Anh: Miles, Slime, Limes. Nhưng mình đang đếm tất cả cách sắp xếp, không chỉ từ có nghĩa.

Một nhóm lặp: EETS

Xét các chữ E, E, T, S. Nếu tất cả khác nhau — giả sử E₁, E₂, T, S — sẽ có 4! = 24 hoán vị.

Nhưng vì hai chữ E giống nhau, hoán đổi E₁ và E₂ cho ra cùng chuỗi. Với mỗi anagram phân biệt, có 2! hoán vị trông giống hệt nhau.

Loading diagram...

Có thể kiểm chứng bằng cách liệt kê hết tất cả:

Bắt đầu bằng EBắt đầu bằng SBắt đầu bằng T
EETSSEETTEES
EESTSETETESE
ETESSTEETSEE
ETSE
ESET
ESTE

6 cách bắt đầu bằng E, 3 cách bằng S, 3 cách bằng T. Tổng cộng là 6 + 3 + 3 = 12, đúng bằng 4!/2!.

Chiến lược: làm các phần tử trùng thành khác nhau, đếm tất cả, rồi chia cho số cách các phần tử trùng tự sắp xếp nội bộ.

Nhiều nhóm lặp: ASSESSOR

Đây chính là lúc công thức phát huy tối đa tác dụng. A-S-S-E-S-S-O-R có 8 chữ:

Chữ cáiSố lần
S4
A1
E1
O1
R1
8!4!×1!×1!×1!×1!=40,32024=1,680\frac{8!}{4! \times 1! \times 1! \times 1! \times 1!} = \frac{40{,}320}{24} = 1{,}680

Công thức tổng quát:

Anagram của multiset=N!k1!×k2!××km!\text{Anagram của multiset} = \frac{N!}{k_1! \times k_2! \times \cdots \times k_m!}

với N là tổng số chữ cái, và k₁, k₂, ..., kₘ là số lần xuất hiện của mỗi chữ phân biệt.

Loading diagram...

Kiểm tra nhanh: tổng các kᵢ phải bằng N. Với ASSESSOR: 4 + 1 + 1 + 1 + 1 = 8. Nếu không khớp, bạn đếm tần suất sai rồi.

Mẹo tô màu

Đây là mô hình giúp mọi thứ trở nên rõ ràng. Lấy ASSESSOR và tô màu mỗi chữ S khác nhau — S₁ đỏ, S₂ xanh dương, S₃ xanh lá, S₄ cam. Bây giờ cả 8 ký tự đều khác nhau, nên có 8! hoán vị.

Nhưng mỗi anagram thực tế ứng với nhiều hoán vị có màu — cụ thể là 4! cái, vì bạn có thể sắp xếp lại 4 chữ S màu mà chuỗi thực tế không đổi.

Loading diagram...

Đây gọi là quy tắc thương — mở rộng sang tập dễ đếm hơn, đếm, rồi chia cho kích thước của từng "nhóm trùng" (tức là số lượng cách sắp xếp trông giống hệt nhau).

Các thẻ chữ S có màu trong ASSESSOR thu gọn thành anagram với chữ lặp

Thử ngay

Nhập bất kỳ từ nào bên dưới và xem số anagram cập nhật theo thời gian thực:

🔠

Máy tính Anagram

Nhập một từ để xem có bao nhiêu cách sắp xếp lại chữ cái

AS1S2ES3S4OR
S ×4A ×1E ×1O ×1R ×1
8! 4!
=
40,320 24
= 1,680
Số anagram phân biệt 1,680

Widget tô màu từng nhóm chữ cái và hiển thị công thức đầy đủ. Thử các từ có nhiều chữ lặp (như "MISSISSIPPI") để thấy số lượng giảm đáng kể so với N!.

Quy tắc thương xuất hiện ở khắp nơi

Công thức anagram là một trường hợp của kỹ thuật rộng hơn: đếm theo nhóm.

  1. Mở rộng sang tập lớn hơn, dễ đếm hơn (ví dụ: coi các vật giống nhau là khác nhau)
  2. Đếm tập mở rộng
  3. Chia cho số phần tử trong mỗi nhóm ứng với một phần tử gốc
Loading diagram...

Kỹ thuật này xuất hiện ở khắp nơi — đếm các hình hình học có tính đối xứng, đếm các hợp chất hóa học có nguyên tử giống nhau, đếm cách chia bài khi thứ tự chất không quan trọng. Chiến lược luôn giống nhau: làm mọi thứ khác nhau, đếm, rồi tính cho các đối xứng.

Một vòng cổ hai màu cho thấy các phép quay được gom vào cùng một lớp tương đương

Nếu ý tưởng tổng quát hóa này hấp dẫn bạn, video Group theory, abstraction, and the 196,883-dimensional monster của 3Blue1Brown là phần tiếp theo tự nhiên — đối xứng → nhóm → quỹ đạo → nhóm hữu hạn 'sporadic' lớn nhất. Quy tắc thương hóa ra chỉ là phần nổi của một tảng băng khổng lồ.

Đang tải video…

Một vài điều mình rút ra được

  • Đếm phần bù thường là cách gọn nhất để xử lý điều kiện "ít nhất một" — đếm tất cả, trừ đi cái không muốn
  • Overcounting xảy ra khi cách xây dựng của bạn có thể tạo ra cùng một đối tượng theo nhiều cách — luôn kiểm tra xem ánh xạ có phải song ánh không
  • Kiểm tra nhanh: nếu số lượng "ít nhất một X" vượt quá tổng số, chắc chắn có gì đó sai
  • Nhiều cách đếm đúng cho cùng bài toán tặng bạn đẳng thức toán học miễn phí — đại số phải khớp vì các tập hợp giống nhau
  • Song ánh biến bài toán đếm lạ thành bài toán quen — nếu ánh xạ là một-một và toàn ánh, số lượng phải bằng nhau
  • Giai thừa đếm cách sắp xếp các vật phân biệt: n! cách sắp xếp n vật
  • 0! = 1 vừa cần thiết về mặt đại số, vừa tự nhiên về mặt tổ hợp — chỉ có đúng một cách sắp xếp không có gì
  • Hoán vị P(n, r) đếm cách chọn r vật từ n vật, mỗi thừa số đại diện cho một lựa chọn bị thu hẹp
  • Anagram của multiset dùng quy tắc thương: N! chia cho tích các giai thừa nhóm lặp
  • Mẹo tô màu là then chốt — làm các vật giống nhau thành khác nhau, đếm, rồi chia đi các đối xứng
  • Khi tổng các giai thừa ở mẫu bằng số ở tử, bạn biết mình đã tính đủ mọi chữ cái
  • Quy tắc thương tổng quát hóa ra ngoài anagram, áp dụng cho mọi tình huống khi bạn có thể mở rộng sang tập dễ hơn rồi chia theo lớp tương đương

Điều cuối cùng — quy tắc thương — là pattern mình thấy quay đi quay lại nhiều nhất. Cùng một ý tưởng dù bạn đang đếm anagram, đối xứng hình học, hay cách sắp xếp mà một số vị trí hoán đổi được. Cứ coi như mọi thứ đều khác nhau cho dễ tính, rồi sau đó mới "chia" bớt cho sự giống nhau. Khi đã biết quy luật này, bạn sẽ thấy nó xuất hiện ở khắp mọi nơi.

Phần 1/2 trong "Discrete Math for Algorithms"


Bình luận