BÀI BÁO CÁO THUẬTTOÁN Đề bài: Giả sử ổ khóa có n công tắc Mỗi công tắc có trạng thái “đóng” hay “mở” Khóa mở có [n/2] công tắc trạng thái “mở” Liệt kê tất cách mở khóa BÀI LÀM: Tóm Tắt Đề Bài: • Input: n công tắt Mỗi công tắt có trạng thái “đóng” hay “mở” Khóa mở có [n/2] công tắt “mở” • Output: Liệt kê tất cách mở khóa Ý Tưởng: • Theo giả thiết cho, ta có: Mỗi công tắt có trạng thái “đóng” hay “mở” => tỉ lệ trạng thái “đóng” trạng thái “mở” • Mặt khác, theo giả thiết cho: Khóa mở có [n/2] công tắt trạng thái mở Nghĩa có [n/2], [n/2+1], [n/2+2],…, [n-1], [n] công tắt trạng thái “mở” khóa mở => Cách giải toán liệt kê tất tập có k phần tử tập n phần tử tổ hợp Cnk (với k = n/2, n/2+1,…, n-1, n) VD: Với n=5 ta liệt 16 cách mở khóa như: (123), (124), (125), (134), (135), (145), (234), (235), (245), (345), (1234), (1235), (1245), (1345), (2345), (12345) VD: Với n= ta liệt kê 11 cách mở khóa: (12), (13), (14), (23), (24), (34), (123), (124), (134), (234), (1234) • Liệt kê tất tập có k phần tử tập n phần tử tổ hợp Cnk (với k chạy từ n/2, n/2+1, n/2+2, n-1,n) Liệt kê tập có k phần tử từ tập n có sẵn ta sử dụng phương pháp sinh từ tập c1, c2, c3, , ck phần tử có trước: Bước 1: Cho j chạy tìm từ vị trí từ bên trái sang vị trí c[i] cho c[i] Tổng thời gian thực là: O(n) Câu lệnh (16), (15), (13), (14), (10), (9), (8) thời gian thực là: O(1) Câu lệnh (12) biến i chạy từ đến k là: O(n) Câu lệnh (11) thực lặp từ k đến n là: O(n) => thời gian thực là: O(n2) Vậy thời gian thục chương trình là: O(n2) Mã hóa ngôn ngữ C: #include #include int d; int c[100]; void inKQ(int k) { int i; d++; printf("\n cach thu %3d:bat den",d); for(i=1;i