Sáng kiến kinh nghiệm THPT: Sử dụng phương pháp chia để trị để giải một số bài toán
lượt xem 2
download
Mục tiêu chính của đề tài là nghiên cứu về phương pháp “Chia để trị” để giải một số bài toán. Giúp cho việc ôn thi học sinh giỏi đạt kết quả cao. Tạo ra nguồn tài liệu tham khảo về phương pháp cũng như thuật toán nhằm hỗ trợ cho học sinh, giáo viên dạy bồi dưỡng học sinh giỏi tin học.
Bình luận(0) Đăng nhập để gửi bình luận!
Nội dung Text: Sáng kiến kinh nghiệm THPT: Sử dụng phương pháp chia để trị để giải một số bài toán
- SỞ GIÁO DỤC VÀ ĐÀO TẠO NGHỆ AN TRƯỜNG THPT THÁI HÒA SÁNG KIẾN KINH NGHIỆM SỬ DỤNG PHƯƠNG PHÁP CHIA ĐỂ TRỊ ĐỂ GIẢI MỘT SỐ BÀI TOÁN Lĩnh vực : Tin học Tên tác giả : Châu Đức Vinh Tổ : Toán Tin Điện thoại : 0942 910 226 Năm học: 2020- 2021 1
- A. PHẦN MỞ ĐẦU I. Lí do chọn đề tài Hiện nay tài liệu dạng chuyên đề nâng cao phục vụ cho việc bồi dưỡng học sinh giỏi môn Tin học là chưa thật sự đầy đủ và tổng quát, đặc biệt là những chuyên đề khá mới và rất khó, giờ đã được đưa vào các đề thi học sinh giỏi tỉnh như: Chia để trị, Quy hoạch động, … Từ thực tiễn giảng dạy tin tại trường THPT tôi thấy rằng để đạt hiệu quả cao trong bồi dưỡng học sinh giỏi, cần có cách thiết kế bài giảng cho phù hợp với nội dung kiến thức dựa trên tài liệu chuyên đề đầy đủ rõ ràng từ lý thuyết đến bài tập và theo đúng xu thế chung của các kì thi học sinh giỏi các cấp hiện nay và trong tương lai, để mang lại thành tích cao cho đội tuyển học sinh giỏi trong các kì thi. Xuất phát từ cơ sở trên, tôi đã chọn đề tài “Sử dụng phương pháp chia để trị để giải một số bài toán”, sáng kiến này sẽ giúp học sinh của trường THPT Thái Hòa vận dụng các kiến thức vào làm tốt các dạng đề thi học sinh giỏi tỉnh có liên quan đến phương pháp chia để trị, phục vụ cho việc bồi dưỡng học sinh giỏi của trường. II. Mục đích của đề tài - Mục tiêu chính của đề tài là nghiên cứu về phương pháp “Chia để trị” để giải một số bài toán. - Giúp cho việc ôn thi học sinh giỏi đạt kết quả cao - Tạo ra nguồn tài liệu tham khảo về phương pháp cũng như thuật toán nhằm hỗ trợ cho học sinh, giáo viên dạy bồi dưỡng học sinh giỏi tin học. III. Đối tượng và phạm vi nghiên cứu 1. Đối tượng nghiên cứu - Sử dụng phương pháp chia để trị và một số bài toán - Học sinh giỏi tin khối 11, giáo viên giảng dạy học sinh giỏi tin 11 2. Phạm vi nghiên cứu Sử dụng phương pháp chia để trị để giải một số bài toán bồi dưỡng học sinh giỏi tin học 11. IV. Phương pháp nghiên cứu - Thu thập, phân tích các tài liệu và thông tin liên quan đến phương pháp chia để trị. - Lựa chọn một số bài toán để sử dụng phương pháp chia để trị. 2
- - Thiết kế các bài toán đã được lựa chọn trong chương trình tin học 11 để bồi dưỡng học sinh giỏi. - Dùng ngôn ngữ lập trình Free Pascal để cài đặt bài toán và chạy thử nghiệm trên một số bộ test để đánh giá kết quả. B. NỘI DUNG SÁNG KIẾN KINH NGHIỆM I. Cơ sở lý luận: - Cách tiếp cận về tri thức mới, hiện đại của học sinh trong trường THPT ở một số trường thuộc trung du miền núi nói chung trong đó có THPT Thái Hòa nói riêng là rất khó khăn vì: Thứ nhất là thiếu tài liệu chuyên sâu về bồi dưỡng học sinh giỏi, thứ hai các em hầu như chưa quan tâm lắm đến lập trình bởi lẽ nó khó. - Vì vậy tôi đã tham khảo tài liệu để viết đề tài về phương pháp chia để trị từ lý thuyết đến thuật toán và có một số bài toán cho các em vận dụng để thực hành trên máy tính. Từ đó các em làm tốt các đề bài có dạng tương tự trong các kì thi chọn học sinh giỏi tin học. II. Nội dung và giải pháp thực hiện 1. Khái niệm: Chia để trị là một tư tưởng rất phổ biến trong cuộc sống và được áp dụng rất hiệu quả trong Tin học. Tư tưởng cơ bản của phương pháp chia để trị là Người ta phân bài toán thành các bài toán con, các bài toán con lại tiếp tục được phân thành các bài toán con nhỏ hơn, cứ tiếp tục như thế cho đến khi ta nhận được bài toán con đã có thuật giải hoặc có thể dễ dàng đưa ra thuật giải. Sau đó kết hợp nghiệm của các bài toán con để nhận được nghiệm của bài toán con lớn hơn để cuối cùng nhận được nghiệm của bài toán cần giải. Thông thường các bài toán con được phân chia là cùng dạng với bài toán ban đầu chỉ có cỡ của chúng là nhỏ hơn. 2. Sơ đồ chung: Các bài toán có thể giải quyết bằng phương pháp chia để trị thông qua 3 bước: Bước 1: Chia: Chia bài toán cần giải thành một loạt các bài toán con độc lập. Tại bước này thì bài toán ban đầu sẽ được chia thành các bài toán con cho đến khi không thể chia nhỏ được nữa. Các bài toán con sẽ trở thành 1 bước nhỏ trong việc giải quyết bài toán lớn. Bước 2. Trị: Giải quyết bài toán con một cách đệ quy. Tại bước này ta sẽ phải tìm phương án để giải quyết cho bài toán con một cách cụ thể. Bước 3. Kết hợp lời giải lại để suy ra lời giải 3
- Khi đã giải quyết xong cái bài toán nhỏ, lặp lại các bước giải quyết đó và kết hợp lại những lời giải đó để suy ra kết quả cần tìm (có thể dạng đệ quy). 3. Thuật toán β: Giả sử chúng ta có thuật toán α để giải bài toán kích thước dữ liệu vào n với thời gian bị chặn bởi cn2 (c: hằng số). Xét thuật giải β để giải bài toán bằng cách: - Bước 1: Chia bài toán cần giải thành 3 bài toán con với kích thước n/2. - Bước 2: Giải 3 bài toán bằng thuật toán α. - Bước 3: Tổng hợp lời giải của 3 bài toán con để thu được lời giải của bài toán. Tính đúng đắn của thuật toán: Giả sử bước 3 đòi hỏi thời gian dn (d: hằng sô). Gọi: T α(n)= thời gian của thuật toán α. T β(n)= thời gian của thuật toán β Ta có: T α(n)= cn2 (theo giả thuyết) T β(n)= 3. T α(n/2) + dn = ¾.cn2 + dn. Nếu: dn < c.n2/4 hay n > 4.d/c thì thuật toán β nhanh hơn thuật toán α. Do 4.d/c là hằng số nên với n đủ lớn ta luôn có n > 4.d/c. Điều đó cho thấy việc sử dụng thuật toán β để giải bài toán đặt ra bằng cách chia nó thành các bài toán con có kích thước càng ngày càng nhỏ đến khi thu được bài toán con kích thước n0 < 4.d/c sẽ thu được hiệu quả cao. 4. Thuật toán chia để trị có thể biểu diễn bằng mô hình đệ quy như sau: Procedure DivideConquer(A,x); //Tìm nghiệm x của bài toán A Begin If (A đủ nhỏ) then Solve(A) Else Begin Phân A thành các bài toán con A1,..., Am; For i:=1 to m do DivideConquer(Ai,xi); Kết hợp nghiệm xi của bài toán con Ai để được nghiệm của bài toán A; 4
- End; End; Chúng ta sẽ nghiên cứu bài toán Tháp Hà nội, là một bài toán điển hình được giải bằng phương pháp chia để trị để thấy được rõ hơn tư tưởng của phương pháp này. Ví dụ. Bài toán Tháp Hà Nội Có N đĩa có đường kính khác nhau được đặt chồng lên nhau theo thứ tự giảm dần của đường kính tính từ dưới lên. Có ba vị trí có thể đặt các đĩa đánh số 1, 2, 3. Chồng đĩa ban đầu được đặt ở vị trí 1: 1 2 3 Cần chuyển cả chồng đĩa từ vị trí 1 sang vị trí 2, theo những quy tắc sau: Khi di chuyển một đĩa, phải đặt nó vào một trong ba vị trí đã cho. Mỗi lần chỉ có thể chuyển một đĩa và phải là đĩa ở trên cùng. Tại một vị trí, đĩa nào mới chuyển đến sẽ phải đặt lên trên cùng. Đĩa lớn hơn không bao giờ được phép đặt lên trên đĩa nhỏ hơn (hay nói cách khác: một đĩa chỉ được đặt trên mặt đất hoặc đặt trên một đĩa lớn hơn) Bài toán này có nguồn gốc là một truyền thuyết của Ấn độ rằng có một nhóm cao tăng Ấn độ giáo được giao trọng trách chuyển dần 64 đĩa vàng giữa 3 cọc kim cương theo các điều kiện đã nói ở phần trên. Khi nào hoàn tất công việc, tức là khi chuyển xong toàn bộ 64 đĩa từ vị trí ban đầu sang vị trí kết thúc thì cũng là thời điểm tận thế. Chúng ta giải bài toán bằng cách chia bài toán chuyển N đĩa, từ vị trí 1 sang vị trí 2 thành ba bài toán đơn giản hơn như sau: 1. Chuyển N-1 đĩa trên cùng từ vị trí 1 sang vị trí 3, dùng vị trí 2 làm trung gian. 2. Chuyển đĩa thứ N từ vị trí 1 sang vị trí 2. 3. Chuyển N-1 đĩa từ vị trí 3 sang vị trí 2, dùng vị trí 1 làm trung gian. Chú ý rằng bài toán 1 và 3 tương tự như bài toán ban đầu, chỉ khác là kích thước nhỏ hơn. Chúng cũng sẽ được giải bằng phương pháp “chia để trị” giống 5
- như bài toán ban đầu. Dễ dàng kiểm tra là khi giải như vậy chúng vẫn thoả mãn các điều kiện. Bài toán 2 thì được giải rất đơn giản. Thuật toán được viết dưới dạng giả mã như sau: Procedure Hanoi; begin Move(n,1,2,3); end; Procedure Move(n,a,b,c); {chuyển n đĩa, từ vị trí a sang vị trí b, dùng vị trí c làm trung gian } begin if n=0 then exit; Move(n-1,a,c,b); writeln('Chuyển đĩa ',n, ' từ vị trí ',a, 'sang vi tri ',b); Move(n-1,c,b,a); end; Chương trình trong Pascal: Program ThapHN; var n:integer; procedure move(n,a,b,c:integer); begin if n=0 then exit; move(n-1,a,c,b); writeln('Chuyen dia ',n,' tu vi tri ',a,' sang vi tri ',b); move(n-1,c,b,a); end; begin write('Nhap N = ');readln(n); move(n,1,2,3); readln end. 6
- Chúng ta hãy dừng lại một chút để phân tích độ phức tạp tính toán. Gọi T(n) là số thao tác chuyển đĩa cần thiết để chuyển xong n đĩa. Theo thuật toán trên ta có: T(n) = T(n-1) + 1 + T(n-1). Bằng các phương pháp giải công thức truy hồi ta có được T(n) = 2n-1. Áp dụng kết quả này với giả thiết rằng mỗi cao tăng phải mất 1 giây để chuyển xong một đĩa từ cọc này sang cọc kia, ta thấy thời gian để chuyển toàn bộ 64 đĩa vàng là T(64)=216-1=18446744073709551615 giây. Như vậy ngày tận thế (nếu có) theo truyền thuyết phải 600 tỉ năm nữa mới đến. Áp dụng phương pháp chia để trị cho bài toán tìm kiếm: 1. Bài toán tìm kiếm Thuật toán tìm kiếm nhị phân Bài toán: Cho dãy A gồm N số nguyên được sắp xếp theo thứ tự không giảm và một số nguyên K. Cho biết có hay không phần tử trong dãy có giá trị bằng K? Ý tưởng: Sử dụng tính chất của dãy tăng ta thu hẹp phạm vi tìm kiếm sau mỗi lần so sánh khóa K với số hạng được chọn. Để làm điều đó ta chọn số hạng AGiữa ở “giữa dãy để so sánh với K, trong đó Giữa = [(n+1)/2]. Khi đó xẩy ra một trong 3 trường hợp sau: - Nếu AGiữa = K thì Giữa là chỉ số cần tìm. Việc tìm kiếm kết thúc. - Nếu AGiữa > K thì do dãy đã được sắp xếp nên việc tìm kiếm tiếp theo chỉ thực hiện trên dãy từ A1 đến AGiữa-1 phạm vi tìm kiếm chỉ khoảng một nửa phạm vi tìm kiếm trước đó. - Nếu AGiữa < K thì thực hiện tìm kiếm trên dãy từ AGiữa+1 đến AN. Quá trình tìm kiếm sẽ kết thúc khi đã tìm thấy khóa K trong dãy A hoặc phạm vi tìm kiếm bằng rỗng. Thuật toán: Bước 1: Nhập N và các số hạng A1 ...AN và khóa K; Bước 2: First=1; Last=N; Bước 3: Mid=[(First+Last)/2]; Bước 4: Nếu AMid=K thì thông báo chỉ số Mid rồi kết thúc; Bước 5: Nếu AMid>K thì Last=Mid-1, rồi chuyển đến bước 7; Bước 6: First=Mid+1; 7
- Bước 7: Nếu First>Last thì thông báo dãy A không có số hạng nào bằng K rồi kết thúc; Bước 8: Quay lại bước 3. Thuật toán tìm kiếm nhị phân có tư tưởng gần giống với thuật toán sắp xếp nhanh. Nó thực hiện việc tìm vị trí trung tâm, thông qua phép so sánh giữa giá trị cần tìm với giá trị tại vị trí trung tâm để quyết định vùng dữ liệu (trước hay sau vị trí trung tâm) mà giá trị đó thuộc về. Việc tìm kiếm sẽ cứ thế tiếp tục trong 1/2 tập hợp dữ liệu vừa xác định với cùng cách thức tìm kiếm, cho tới khi giá trị tại vị trí trung tâm là giá trị cần tìm hoặc phạm vi tìm kiếm bằng rỗng thì dừng. Vì sau mỗi bước tìm kiếm miền dữ liệu lại giảm đi phân nữa, số lượng các bước tìm kiếm cũng tăng dần tới tối đa là log2(N). Vì vậy độ phức tạp của thuật toán này được xem là O(logN). Chúng ta sẽ xem cách cài đặt thuật toán thông qua ví dụ sau: Bài toán áp dụng: Bài 1. Bài toán Hẹn gặp Thành phố Gloaming (Hoàng hôn) nổi tiếng với đường dẫn vào công viên thành phố. Các bức tượng tuyệt đẹp theo chủ đề thần thoại Hy lạp – La mã đặt dọc theo con đường thẳng có một sức hút không cưỡng được với mọi khách dulịch. Còn khi những tia nắng cuối cùng trong ngày miễn cưỡng rời khỏi bầu trời thì sương mù dày đặc, như một tấm voan trắng mềm mại từ từ rũ xuống. Bây giờ đứng cách quá r mét là đã không nhìn thấy mặt nhau và các bức tượng trở thành nơi lý tưởng cho các đôi nam nữ thanh niên hẹn hò. James Bond cần gặp gấp 2 điệp viên nội tuyến của mình để nhận các mật báo khẩn. Không muốn 2 người này nhìn thấy nhau, Bond hẹn gặp mỗi người ở một bức tượng sao cho khoảng cách giữa chúng lớn hơn r. Trên đường có n bức tượng, bức tượng thứ i ở vị trí cách đầu con đường di mét i = 1 ÷ n, 1 ≤ d1< d2 < .. .< dn ≤ 109. Yêu cầu: Hãy xác định James Bond có bao nhiêu cách chọn địa điểm. Dữ liệu vào: Vào từ file văn bản BAI1.INP: - Dòng đầu tiên chứa 2 số nguyên n và r (1 ≤ n ≤ 3×105, 1 ≤ r ≤ 109). - Dòng thứ 2 chứa n số nguyên d1, d2, . . ., dn. Kết quả: Đưa ra file văn bản BAI1.OUT một số nguyên là số cách chọn địa điểm tìm được 8
- Ví dụ: BAI 1. INP BAI 1.OUT 44 2 1358 Rằng buộc: - Có ½ số test tương ứng với ½ số điểm có n ≤ 104 - Có ½ số test tương ứng với ½ số điểm có 104 < n ≤ 3×105 Thực trạng: Với cách tư duy thông thường học sinh sẽ khai báo mảng lưu trữ vị trí di. Sử dụng 2 vòng lặp for do để kiểm tra r + d[i]< d[j] thì dừng lại để cộng vào biến đếm. Khi đó độ phức tạp của thuật toán sẽ O(n2), mà theo giới hạn đầu bài 1≤n≤3x105 nên với n max thì số lượng phép toán phải thực hiện là: 3x105x 3x105. Nếu gặp test này thì chắc chắn chương trình không thể thực hiện trong 1 giây. Procedure xuli; Var i,j:int64; Begin Dem:=0; For i:=1 to n do For j:=i to n do If r+d[i]
- d:array[1.. 300000]of longint; n,r,i:longint; dem:int64; procedure taotep; begin Assign(f1,fi); assign(f2,fo); Reset(f1); rewrite(f2); end; procedure doctep; var i:longint; begin readln(f1,n,r); for i:=1 to n do read(f1,d[i]); end; function np(x,a,b:longint):longint; var t,p,m:longint; Begin t:=a; p:=b; while t
- dem:=0; for i:=1 to n do begin a:=np(r+d[i],I,n); if a>n then break; inc(dem,n-a+1); end; End; procedure ghitep; Begin Writeln(f2,dem); End; procedure dongtep; begin close(f1); close(f2); end; BEGIN Taotep; doctep; xuli; ghitep; dongtep; END. Bài 2. Cho một dãy gồm N số nguyên dương, xác định xem có tồn tại hay không dãy con liên tiếp có tổng bằng K hay không? Dữ liệu: Vào từ file văn bản Bai2.inp: Dòng đầu tiên ghi số n và k 2 số cách nhau bới dấu cách; Dòng thứ hai ghi N số nguyên dương. Kết quả: Ghi ra file văn bản Bai2.out: Chỉ một dòng duy nhất là dãy con cần tìm (Nếu không có thì ghi số 0). Thực trạng: Với bài toán này ta có thể thực hiện bằng cách duyệt tất cả các dãy con có thể có từ dãy N phần tử và thực hiện tính tổng của dãy con đó rồi so sánh với K. Giải thuật có thể thực hiện như sau: For i:=1 to N do 11
- Begin S:=0; For j:=i to N do S:=S+A[j]; If s=k then begin write(‘tim thay’);break; end; End; Thuật toán trên cho ta độ phức tạp cỡ O(n2). Giải pháp: Ta có thể cải tiến thuật toán bằng cách sau: - Tạo dãy S trong đó Si=A1+...+Ai; - Nhận thấy do dãy A gồm các số nguyên dương nên dãy S là tăng dần. - Để xác định đoạn [Ai,Aj] có tổng các phần tử bằng K hay không ta thực hiện tìm kiếm nhị phân trên đoạn từ vị trí i đến vị trí j trong dãy S mà Sj-Si=K. Giải thuật như sau: Bước 1. Tạo dãy S từ dãy A: S[0]:=0; Với mỗi i nhận giá trị từ 1 đến n làm S[i]:=S[i-1]+A[i]; Bước 2. Res=-1; {Res dùng để đánh dấu vị trí cuối của dãy con cần tìm} Bước 3. Với mỗi i nhận giá trị từ 1 đến N làm: 3.1 Cho first:=i; last:=n; 3.2 chừng nào firstk thì last:=mid-1; first:=mid+1; 3.3. Nếu Res-1 thì đưa dãy con cần tìm là dãy Ai+1 đến ARes. Và kết thúc. Bước 4. Đưa ra kết luận không tìm thấy và kết thúc. 12
- Đánh giá độ phức tạp của thuật toán: Ta thấy thời gian thực hiện thuật toán trên bằng tổng thời gian thực hiện của chương trình con doctep (cỡ O(n)) và chương trình con xuli; Do việc tìm chỉ số res chỉ thực hiện trên nửa dãy Ai đến An (với i= 1 đến n) nên chương trình con xuli có độ phức tạp cỡ O(nlogn). Vậy thuật toán giải bài toán trên có độ phức tạp cỡ O(nlogn). Thuật toán này còn có thể cải tiến để có độ phức tạp cỡ O(n) chúng ta sẽ xem xét vấn đề này trong chuyên đề khác. Nhưng với tư tưởng chia để trị và thuật toán tìm kiếm nhị phân chúng ta thấy độ phức tạp của thuật toán được cải thiện phần nào. Bài toán tìm kiếm nhị phân có đầu vào là các dãy đã sắp xếp nên một số bài tập có sự kế thừa từ thuật toán sắp xếp. Chương trình tham khảo: const fi=’Bai2.INP’; fo=’Bai2.OUT’; var n,k:longint; F1,F2:TEXT; a:array[1..100000]of longint; s:array[0..100000]of longint; procedure taotep; begin Assign(f1,fi); assign(f2,fo); Reset(f1); rewrite(f2); end; procedure doctep; var i:longint; begin fillchar(s,sizeof(s),0); readln(f1,n,k); for i:=1 to n do begin read(f1,a[i]); s[i]:=s[i-1]+a[i]; end; end; 13
- procedure xuli; var first,mid,last,i,res,id:longint; begin res:=-1; for i:=0 to n-1 do begin first:=i; last:=n; while firstk then last:=mid-1 else first:=mid+1; end; if res-1 then begin write(f2,'day la: ',i+1,'...',res); break; end else begin write(f2,0); break; end; end; 14
- end; procedure dongtep; begin close(f1); close(f2); end; BEGIN Taotep; doctep; xuli; dongtep; END. Bài 3: Cho dãy A gồm N số nguyên a1,..,an đã được sắp xếp theo thứ tự không giảm và một khóa K. Hãy chèn khóa K vào dãy A sao cho dãy đó vẫn đảm bảo thứ tự không giảm. Dữ liệu: Vào từ file văn bản Bai3.inp: Dòng đầu tiên ghi số n và khóa k 2 số cách nhau bới dấu cách; Dòng thứ hai ghi N số nguyên. Kết quả: Ghi ra file văn bản Bai3.out: Chỉ một dòng duy nhất là dãy sau khi chèn. Ý tưởng: Ta cần xác định vị trí vt để chèn khóa K. Thực hiện tìm kiếm nhị phân trên dãy A để tìm vị trí vt thõa mãn avtK. Đẩy các phần tử từ vt đến n lùi 1 xuống một vị trí. Đặt avt=K. Tăng n lên 1 đơn vị. Đánh giá thuật toán: Việc tìm vị trí chèn khóa K có thể thực hiên bằng cách tìm tuần tự từ đầu đến cuối dãy và thuật toán có độ phức tạp cỡ O(n). Nếu thực hiện tìm kiếm nhị phân trên nữa dãy với khóa tìm kiếm K, thuật toán có độ phức tạp cỡ O(logn). Chương trình tham khảo: const fi=’Bai3.INP’; fo=’Bai3.OUT’; var F1,F2:TEXT; 15
- a:array[1.. 100001]of longint; n,k,vt,i:longint; procedure taotep; begin Assign(f1,fi); assign(f2,fo); Reset(f1); rewrite(f2); end; procedure doctep; var i:longint; begin readln(f1,n,k); for i:=1 to n do read(f1,a[i]); end; procedure xuli; var first,mid,last,i:longint; begin first:=1; last:=n; if Ka[n] then vt:=n+1 else while first
- end; write(vt); a[n+1]:=0; for i:=n downto vt do a[i+1]:=a[i]; a[vt]:=K; inc(n); end; procedure ghitep; begin Writeln(f2,'Day sau khi chen la: '); for i:=1 to n do write(f2,a[i],' '); end; procedure dongtep; begin close(f1); close(f2); end; BEGIN Taotep; doctep; xuli; ghitep; dongtep; END. Áp dụng phương pháp chia để trị cho bài toán sắp xếp: 1. Bài toán sắp xếp Bài toán: Cho dãy A gồm N số nguyên. Sắp xếp dãy A thành dãy không giảm. Bài toán sắp xếp là bài toán quen thuộc và có nhiều thuật toán để giải bài toán này. Các thuật toán Sắp xếp nổi bọt (Bubble Sort) hay chèn trực tiếp (Insertion Sort) đều có độ phức tạp cỡ O(n2). Thuật toán sắp xếp nhanh (Quick Sort) hay sắp xếp trộn (Merge Sort) là hai thuật toán sắp xếp theo tư tưởng chia để trị. 0Với tư tưởng chia để trị, Quick Sort và Merge Sort cho ta độ phức tạp nhỏ hơn thường là O(nlogn). Trong đề tài này tôi chỉ tập trung nghiên cứu thuật toán QuickSort Chúng ta xét thuật toán sắp xếp nhanh (Quick Sort) Ý tưởng: Tư tưởng của thuật toán này là chia để trị, ta tìm cách chia đôi dãy ban đầu bằng cách chọn ra một phần tử là chốt (pivot). Từ dãy ban đầu, tất cả phần 17
- tử nhỏ hơn phần tử chốt thì đưa về bên trái dãy; những phần tử lớn hơn hoặc bằng chốt thì đưa về bên phải dãy. Sau bước này ta có phần tử chốt là đứng đúng vị trí. Dãy ban đầu được chia thành hai dãy con nằm hai bên chốt. Tiếp tục phân chia các dãy con theo cách tương tự cho đến khi mọi dãy con đều có độ dài bằng 1. Có thể chọn phần tử chốt nằm đầu, cuối, giữa dãy hoặc chọn ngẫu nhiên một phần tử trong dãy. Giải Thuật: Trường hợp sau chọn chốt là phần tử giữa dãy Sắp xếp một đoạn bất kỳ A[L] ... A[R] với điều kiện L
- if il then quicksort(l,j); end; Đánh giá độ phức tạp Việc chọn chốt để phân đoạn quyết định hiệu quả của thuật toán, nếu chọn chốt không tốt rất có thể việc phân đoạn bị suy biến thành trường hợp xấu khiến QuickSort hoạt động chậm. + Trường hợp tốt nhất: mỗi lần phân hoạch ta đều chọn được phần tử median (phần tử lớn hơn hay bằng nửa số phần tử và nhỏ hơn hay bằng nửa số phần tử còn lại) làm chốt. Khi đó dãy được phân đoạn thành hai phần bằng nhau, và ta cần log2(n) lần phân đoạn thì sắp xếp xong. Ta cũng dễ nhận thấy trong mỗi lần phân đoạn ta cần duyệt qua n phần tử. Vậy độ phức tạp trong trường hợp tốt nhất cỡ O(nlogn). + Trường hợp xấu nhất: mỗi lần phần đoạn ta chọn phải phần tử có giá trị cực đại hoặc cực tiểu làm mốc. Khi đó dãy bị phân đoạn thành hai phần không đều: một phần chỉ có một phần tử, phần còn lại có n-1 phần tử. Do đó, ta cần tới n lần phân đoạn mới sắp xếp xong. Vậy độ phức tạp trong trường hợp xấu nhất thuộc O(n2). Trường hợp này ít khi xẩy ra nếu việc chọn chốt là ngẫu nhiên. Bài toán áp dụng: Bài 1. Camera theo dõi Trong đoạn đường từ thành phố A đến thành phố B có N nút giao thông đánh số từ 1 đến N (với AB là một đoạn thẳng). Cần bố trí các camera theo dõi hoạt động giao thông tại các nút này. Mỗi camera đặt ở một vị trí nào đó có thể theo dõi được hoạt động giao thông trên những điểm ở cách nó không quá r (km). Bieets di (km) là khoảng cách từ nút giao thông A đến nút giao thông thứ I (i=1,2,…,N). Yêu cầu: Tìm cách đặt một số ít nhất camera để có thể theo dõi được hoạt động giao thông trên đoạn đường từ A đến B (mỗi nút phải nằm tròng tầm theo dõi của ít nhất một trong số các camera được bố trí). Dữ liệu: Vào từ file văn bản CAMERA.INP gồm: - Dòng đầu tiên ghi số nguyên dương N (N
- - Dòng thứ i trong số N dòng tiếp theo ghi số thực d (i=1,2….,N) là một trong những khoảng cách từ thành phố A đến một nút giao thông bất kỳ. Kết quả: Ghi ra file văn bản CAMERA. OUT gồm: - Dòng đầu tiên ghi k là số lượng máy theo dõi cần đặt. - Dòng thứ i trong số k dòng tiếp theo ghi Si là khoảng cách từ A đến vị trí đặt camera thứ i (các camera đặt theo thứ tự sao cho: S1
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Sáng kiến kinh nghiệm THPT: Thiết kế và ứng dụng học liệu số trong nâng cao hứng thú và hiệu quả dạy học Lịch sử lớp 10 Bộ Cánh diều
49 p | 64 | 29
-
Sáng kiến kinh nghiệm THPT: Tăng cường sử dụng phương pháp dạy học trực quan vào giảng dạy môn Toán THPT
37 p | 43 | 13
-
Sáng kiến kinh nghiệm THPT: Khai thác và sử dụng các biến nhớ của máy tính điện tử cầm tay trong chương trình Toán phổ thông
128 p | 148 | 11
-
Sáng kiến kinh nghiệm THPT: Sử dụng sơ đồ phân bố thời gian giúp học sinh giải nhanh bài tập trắc nghiệm liên quan đến thời điểm và khoảng thời gian trong mạch dao động
24 p | 27 | 9
-
Sáng kiến kinh nghiệm THPT: Sử dụng các bài hát, tục ngữ, ca dao trong dạy học Địa lí 10, 12
31 p | 66 | 9
-
Sáng kiến kinh nghiệm THPT: Sử dụng kĩ thuật giao nhiệm vụ nhằm nâng cao hiệu quả về năng lực tự quản, khả năng giao tiếp và hợp tác nhóm cho học sinh lớp 11B4 - Trường THPT Lê Lợi
13 p | 119 | 8
-
Sáng kiến kinh nghiệm THPT: Sử dụng sơ đồ tư duy hệ thống, khắc sâu kiến thức Hoá học hữu cơ lớp 12 cơ bản
30 p | 43 | 8
-
Sáng kiến kinh nghiệm THPT: Sử dụng phiếu học tập dưới dạng đề kiểm tra sau mỗi bài học, để học sinh làm bài tập về nhà, làm tăng kết quả học tập môn Hóa
13 p | 28 | 8
-
Sáng kiến kinh nghiệm THPT: Sử dụng Infographic nhằm nâng cao hiệu quả và tăng hứng thú học tập Ngữ văn của học sinh THPT
15 p | 24 | 7
-
Sáng kiến kinh nghiệm THPT: Sử dụng sơ đồ tư duy giúp học sinh lớp 12 trường THPT Trần Đại Nghĩa làm bài kiểm tra đạt hiệu quả cao
41 p | 57 | 7
-
Sáng kiến kinh nghiệm THPT: Phân loại và phương pháp giải bài tập chương andehit-xeton-axit cacboxylic lớp 11 THPT
53 p | 29 | 6
-
Sáng kiến kinh nghiệm THPT: Sử dụng thí nghiệm ảo trong dạy học phần điện từ học lớp 11 THPT
38 p | 55 | 6
-
Sáng kiến kinh nghiệm THPT: Sử dụng bản đồ tư duy (mind map) để tổng hợp kiến thức ôn thi tốt nghiệp và đại học cho học sinh khối 12
6 p | 56 | 6
-
Sáng kiến kinh nghiệm THPT: Một số giải pháp nhằm nâng cao chất lượng bồi dưỡng học sinh giỏi phần Lịch sử thế giới hiện đại (1945 - 2000)
24 p | 119 | 6
-
Sáng kiến kinh nghiệm THPT: Hướng dẫn học sinh lớp 12 ôn tập môn Lịch Sử theo định hướng 5 bước 1 vấn đề, đáp ứng yêu cầu mới của kỳ thi THPT Quốc gia
29 p | 36 | 5
-
Sáng kiến kinh nghiệm THPT: Một số biện pháp nhằm nâng cao nhận thức và kĩ năng sử dụng tiếng Việt của học sinh trường THPT Nguyễn Thị Giang
21 p | 48 | 4
-
Sáng kiến kinh nghiệm THPT: Sử dụng bảng hệ thống kiến thức nhằm nâng cao chất lượng trong ôn thi tốt nghiệp trung học phổ thông phần Lịch sử Việt Nam (1919-1945)
47 p | 42 | 2
-
Sáng kiến kinh nghiệm THPT: Lồng ghép một số tư liệu lịch sử Bình Long trong dạy học lịch sử Việt Nam giai đoạn 1954 -1975
16 p | 54 | 2
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn