Hướng dẫn giải của Zapina


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Subtask ~1~ có thể giải bằng cách đơn giản kiểm tra xem với mỗi cách phân phát bài toán, có tồn tại ít nhất một lập trình viên cảm thấy hài lòng hay không. Tổng cộng có ~N^N~ cách phân phát.

Subtask ~2~ có thể giải bằng nguyên lý bao hàm – loại trừ. Gọi ~a(S)~, với ~S \subseteq \{1,2,\ldots,N\}~, là số cách phân phát sao cho tất cả các lập trình viên trong tập ~S~ đều hài lòng. Khi đó, số cách tốt (có ít nhất một người hài lòng) là:

~\sum_{S \subseteq \{1,2,\ldots,N\}} (-1)^{|S|+1} a(S)~

Giả sử ~S = \{s_1, s_2, \ldots, s_k\}~. Nếu ~s_1\ + s_2\ + \ldots + s_k > N~ thì rõ ràng ~a(S) = 0~. Ngược lại, ta có:

~a(S) = \binom{N}{s_1} \binom{N - s_1}{s_2} \cdots \binom{N - (s_1 + \cdots + s_{k-1})}{s_k} \cdot (N - k)^{\,N - (s_1 + \cdots + s_k)}~

Các hệ số tổ hợp có thể được tiền xử lý bằng công thức quen thuộc:

~\binom{n}{k} = \binom{n-1}{k-1} + \binom{n-1}{k}~

với độ phức tạp ~O(N^2)~.

Độ phức tạp tổng thể của cách này là ~O(N * 2^N)~.

Cuối cùng, subtask ~3~ (bài đầy đủ) có thể giải bằng quy hoạch động.

Gọi ~dp(n,\ k)~ là số cách phân phát ~k~ bài toán cho ~n~ lập trình viên sao cho có ít nhất một lập trình viên hài lòng.

Có hai trường hợp:

  1. Giao cho lập trình viên thứ ~n~ đúng ~n~ bài toán (khi đó người này hài lòng). Nếu ~k ≥ n~, số cách là: ~\binom{k}{n} \cdot (n-1)^{\,k-n}~

  2. Không giao đúng ~n~ bài cho lập trình viên thứ ~n~. Khi đó: ~\sum_{\substack{0 \le i \le k \\ i \ne n}} \binom{k}{i} \cdot dp(n-1, k-i)~

Độ phức tạp của lời giải này là ~O(N^3)~.


Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.