Trong bối cảnh đó, việc dạy học lập trình cho học sinh là một việc tất yếu, nhằm tạo tiền đề kiến thức về công nghệ thông tin cho thế hệ trẻ, những chủ nhân tương lai của xã hội.Tuy nhiê
Trang 1MỤC LỤC Trang
PHẦN I MỞ ĐẦU……… ……… 1
1 Lí do chọn đề tài 1
2 Mục đích nghiên cứu 1
3 Nhiệm vụ của đề tài 1
4 Đối tượng nghiên cứu 2
5 Phạm vi nghiên cứu……… ……… 2
6 Phương pháp nghiên cứu……… 2
PHẦN II NỘI DUNG……… … 3
1 Cơ sở lí luận 3
2 Thực trạng ……… … 3
3 Biện pháp 3
3.1 Cơ sở lí thuyết……… 3
3.2 Bài tập vận dụng 4
4 Hiệu quả của đề tài 17
BÀI TẬP THAM KHẢO.……… ……….……… 17
PHẦN III KẾT LUẬN……….……… 20
3.1 Kết luận 20
3.2 Kiến nghị 20
Tài liệu tham khảo 22
Danh mục các đề tài SKKN đã đạt giải cấp tỉnh 23
PHẦN I MỞ ĐẦU
Trang 21 Lí do chọn đề tài
Chúng ta đang ở trong kỷ nguyên kỹ thuật số với nền cách mạng công nghiệp 4.0.Ứng dụng công nghệ thông tin hiện hữu ở mọi nơi, mọi lúc và mọi phương diện trong xãhội Trong bối cảnh đó, việc dạy học lập trình cho học sinh là một việc tất yếu, nhằm tạo tiền
đề kiến thức về công nghệ thông tin cho thế hệ trẻ, những chủ nhân tương lai của xã hội.Tuy nhiên, do đặc thù của môn học, là môn học mới, các em được tiếp cận ít Năng lực tưduy thuật toán là rất khó, nên việc triển khai đồng đều ở các địa phương, vùng miền là rấtkhó khăn từ cấp độ đại trà chứ chưa nói gì đến mũi nhọn
Công tác bồi dưỡng học sinh giỏi là một công tác mũi nhọn trong việc nâng cao chấtlượng giáo dục, tạo nguồn lực, bồi dưỡng nhân tài cho nhà trường nói riêng và xã hội nóichung Đây là một công việc khó khăn và lâu dài, đòi hỏi rất nhiều công sức của thầy và trò
Là một giáo viên đứng đội tuyển nhiều năm, tôi đã dành nhiều thời gian để tìm kiếm, sưutầm, phân loại một số bài tập lập trình nhằm phân loại theo chuyên đề và chọn ra các bài tậpphù hợp để đưa vào dạy học sinh
Từ những lý do trên tôi xin trình bày sáng kiến kinh nghiệm “Áp dụng kĩ thuật tham lam để giải một số bài toán trong Tin học góp phần nâng cao tư duy,
kĩ năng lập trình và chất lượng bồi dưỡng học sinh giỏi ”, để học sinh dễ
dàng làm quen, tiếp thu và hình thành kĩ năng trong việc tiếp cận một số bàitoán thực tế trong lập trình, nhằm giúp các em phát huy tính tích cực, yêu thích nângcao tư duy, kỹ năng lập trình của mình
2 Mục đích nghiên cứu
Mục đích của đề tài này là cung cấp một phương pháp/ kỹ thuật trong việc giải quyết một số bài toán thực tế mang tính chất lựa chọn tối ưu Đồng thời đưa ra các ví dụ để học sinh có thể làm quen, hình thành các kĩ năng trong việc tiếp cận và lựa chọn kĩ thuật tham
lam
3 Nhiệm vụ của đề tài
-Tham khảo các bài tập tin học, bài tập nâng cao, tài liệu ôn luyện học sinh giỏi và một số đềthi học sinh giỏi môn Tin học
Trang 3- Nghiên cứu các tài liệu liên quan đến kĩ thuật tham lam trong lập trình và rút ra phươngpháp làm quen và vận dụng kĩ thuật này.
- Hướng dẫn cho học sinh làm quen và hình thành kĩ năng để giải một số bài toán cụ thể
- Kiểm tra, đánh giá kết quả của học sinh trong quá trình triển khai đề tài để từ đó có nhữngđiều chỉnh, bổ sung hợp lí
4 Đối tượng nghiên cứu
- Kỹ thuật tham ăn trong lập trình và các bài tập Tin học liên quan đến kỹ thuật này
5 Phạm vi nghiên cứu
- Học sinh lớp 11 trường THPT Thọ Xuân 4
- Các bài tập, đề thi Tin học
6 Phương pháp nghiên cứu
Sáng kiến kinh nghiệm đang trình bày của tôi dựa theo các luận cứ khoa học hướng đốitượng, vận dụng linh hoạt các phương pháp: quan sát, thuyết trình, vấn đáp, điều tra cơ bản,kiểm thử, phân tích kết quả thực nghiệm sư phạm…vv phù hợp với bài học và môn họcthuộc lĩnh vực cấu trúc dữ liệu
Trang 4PHẦN II NỘI DUNG
1 Cơ sở lí luận
Chúng ta thấy rằng hiện nay giáo dục đang từng bước triển khai chươngtrình giáo dục phổ thông mới, trong đó môn Tin học ngày càng khẳng định vaitrò chủ đạo trong việc trang bị cho người học khả năng tìm kiếm, tiếp cận, mởrộng tri thức và sáng tạo trong thời đại cách mạng công nghiệp 4.0 Tin học đãđược đưa vào dạy chính khóa ở cấp trung học phổ thông từ năm 2005
Ngoài việc trang bị kiến thức, kĩ năng Tin học cơ bản cho toàn bộ họcsinh thì nhu cầu phát hiện, bồi dưỡng học sinh giỏi môn Tin học ngày càngđược chú trọng Các cuộc thi tin học dành cho học sinh càng có quy mô lớn,nhiều lứa tuổi khác nhau, thu hút đông đảo các bạn trẻ tham gia và trở thành
mối quan tâm chung của các nhà trường
2 Thực trạng
Tuy nhiên, lượng sách tham khảo, sách bài tập dạy lập trình cho học sinhphổ thông là khá nghèo nàn, thiếu đa dạng, dẫn đến việc tiếp cận với việc họclập trình của học sinh gặp nhiều khó khăn chứ chưa nói gì đến phân loại, phândạng bài tập theo chuyên đề để ôn luyện nâng cao chất lượng mũi nhọn Bêncạnh đó, giáo viên dạy môn Tin cũng đang thiếu nguồn tài liệu tham khảo phục
vụ cho dạy học lập trình
Với một chút kinh nghiệm bản thân, tôi đã sưu tầm, phân loại một số bàitập lập trình liên quan đến kĩ thuật tham lam, làm nguồn tài liệu giảng dạy chobản thân và muốn chia sẻ đến thầy cô và các bạn học sinh quan tâm
3 Biện pháp
3.1 Cơ sở lý thuyết
Kĩ thuật tham lam là gì ?
Tham lam (hay tham ăn) là một trong những phương pháp phổ biến nhất
để thiết kế giải thuật Nếu bạn đã đọc truyện dân gian thì sẽ có câu chuyện nhưthế này: trên một mâm cỗ có nhiều món ăn, món nào ngon nhất ta sẽ ăn trước,
ăn hết món đó ta sẽ chuyển sang món ngon thứ hai, và chuyển tiếp sang mónthứ ba, …
Rất nhiều giải thuật nổi tiếng được thiết kế dựa trên ý tưởng tham lam, ví dụnhư giải thuật cây khung nhỏ nhất của Dijkstra, giải thuật cây khung nhỏ nhấtcủa Kruskal, …
Kỹ thuật tham lam lựa chọn giải pháp nào được cho là tốt nhất ở thờiđiểm hiện tại và sau đó giải bài toán con nảy sinh từ việc thực hiện lựa chọn đó.Lựa chọn của kỹ thuật tham lam có thể phụ thuộc vào lựa chọn trước đó Việcquyết định sớm và thay đổi hướng đi của giải thuật cùng với việc không bao giờxét lại các quyết định cũ sẽ dẫn đến kết quả là phương pháp này không tối ưu
để tìm giải pháp toàn cục
Chúng ta hãy theo dõi một bài toán đơn giản dưới đây để thấy cách thực hiệngiải thuật tham lam và vì sao lại có thể nói rằng giải thuật này là không tối ưu
Trang 5Ví dụ: Xét bài toán đếm số đồng tiền
Yêu cầu là hãy lựa chọn số lượng đồng tiền nhỏ nhất có thể sao cho tổng mệnhgiá của các đồng tiền này bằng với một lượng tiền cho trước
Nếu tiền đồng có các mệnh giá lần lượt là 1, 2, 5, và 10 xu và lượng tiền chotrước là 18 xu thì giải thuật tham lam thực hiện như sau:
Bước 1: Chọn đồng 10 xu, do đó sẽ còn 18 – 10 = 8 xu.
Bước 2: Chọn đồng 5 xu, do đó sẽ còn là 3 xu.
Bước 3: Chọn đồng 2 xu, còn lại là 1 xu.
Bước 4: Cuối cùng chọn đồng 1 xu và giải xong bài toán.
Bạn thấy rằng cách làm trên là khá ổn, và số lượng đồng tiền cần phải lựa chọn
là 4 đồng tiền Nhưng nếu chúng ta thay đổi bài toán trên một chút thì cũnghướng tiếp cận như trên có thể sẽ không đem lại cùng kết quả tối ưu
Chẳng hạn, một hệ thống tiền tệ khác có các đồng tiền có mệnh giá lần lượt là
1, 7 và 10 xu và lượng tiền cho trước ở đây thay đổi thành 15 xu thì theo giảithuật tham lam thì số đồng tiền cần chọn sẽ nhiều hơn 4 Với giải thuật thamlam thì: 10 + 1 + 1 +1 + 1 + 1, vậy tổng cộng là 6 đồng tiền Trong khi cùng bàitoán như trên có thể được xử lý bằng việc chỉ chọn 3 đồng tiền (7 + 7 +1)
Do đó chúng ta có thể kết luận rằng, giải thuật tham lam tìm kiếm giải pháp tối
ưu ở mỗi bước nhưng lại có thể thất bại trong việc tìm ra giải pháp tối ưu toàncục
Ưu điểm của tham lam
Thuật toán tham lam dễ dàng tiếp cận với các bài toán đặc biệt là các bàitoán đồ thị và NP-đầy đủ mặc dù không đảm bảo tìm ra được lời giải tối
ưu tuy nhiên nó vẫn trở nên rất hữu ích bởi việc dễ dàng thiết kế để cho ralời giải ước lượng (tương đối chính xác)
Độ phức tạp của tham lam là khá rõ ràng từ đó bạn có thể xem xét độ phùhợp của tham lam đối với thời gian chạy của bài toán cần giải quyết
Nếu có thể chứng minh rằng một thuật toán tham lam cho ra kết quả tối
ưu toàn cục cho một lớp bài toán nào đó, thì thuật toán thường sẽ trởthành phương pháp được chọn lựa, vì nó chạy nhanh hơn các phươngpháp tối ưu hóa khác như quy hoạch động
Nhược điểm
Rất khó để hiểu hay chứng minh 1 lời giải tham lam là kết quả tối ưu ngay
kể cả khi nó đưa ra lời giải tối ưu
3.2 Bài tập vận dụng
Bài 1 Đĩa CD Tên file: CD.***
Bạn An có N file nhạc đuôi mp3, có dung lượng lần lượt là A1, A2, , AN.Bạn An muốn ghi một số file nhạc đó vào một chiếc đĩa CD có dung lượng là S.Hãy giúp bạn An cần chọn ra nhiều file nhạc nhất để ghi vào đĩa CD
Input: - Dòng 1 chứa hai số N (1 <= N <= 100) và S cách nhau 1 dấucách
- Dòng 2 chứa các số A1, A2, , AN
Trang 6Output: Số lượng file nhạc nhiều nhất để ghi vào đĩa CD.
Ví dụ:
5 16
9 4 4 12 7
dung lượng lần lượt là 4 4 và 7
Ý tưởng: Ta thấy rằng dung lượng S của đĩa là không thay đổi Để chọn ra được
nhiều file nhạc nhất để ghi vào đĩa CD thì kĩ thuật tham lam ở đây là: chọnfile
có dung lượng nhỏ ghi trước, file có dung lượng lớn ghi sau
Thuật toán đề xuất:
int d=0; // số file nhạc ban đầu;
int t=0; // tổng dung lượng file nhạc hiện có trong đĩa
for (int i=1;i<=n;i++)
Bài 2 MUA HÀNG Tên file: BUY.CPP
Một công ty muốn mua m máy tính Sau khi lấy thông tin tại n cửa hàng (1
n 10000), người ta biết được rằng cửa hàng thứ i có bán ai máy tính và vớigiá mỗi máy tính là bi (ai, bi là những số nguyên dương: ai 100; bi 2000)
Trang 7Giả sử rằng các cửa hàng có đủ máy để bán cho công ty Hãy tìm cách mua
rẻ nhất.
Dữ liệu: Vào từ file văn bản BUY.INP
Dòng 1: Chứa hai số m, n cách nhau ít nhất một dấu cách
n dòng tiếp theo, dòng thứ i chứa hai số ai, bi cách nhau ít nhất một dấu cách
Kết quả: Ghi ra file văn bản BUY.OUT
Dòng 1: Ghi tổng số tiền phải trả
n dòng tiếp theo, dòng thứ i ghi số máy tính mua ở cửa hàng thứ i
Ý tưởng: Theo đề bài ra yêu cầu mua đủ m máy tính tại n cửa hàng sao cho giá
mua là rẻ nhất (không đề cập đến chất lượng) Vậy thì phương án tối ưu nhất ởđây là dùng kĩ thuật/chiến lược tham lam là chọn cửa hàng bán rẻ nhất để mua,mua hết, mua đủ số lượng m máy sao cho số tiền bỏ ra là ít nhất
Bước 1: Sắp xếp các cửa hàng tăng dần theo giá của máy tính.
Bước 2: Chọn mua máy tính ở cửa hàng thứ 1n cho đến khi đủ m máy tính thì
thôi
Trong bài này sẽ sử dụng kiểu struct cho cuahang gồm 3 biến:
Biến a: số lượng máy tính hiện có ở mỗi cửa hàng
b: giá bán của một chiếc máy tính ở cửa hàng
id: chỉ số của cửa hàng
Thuật toán đề xuất:
int n, m, tien = 0, somay = 0;
bool cmp(cuahang X, cuahang Y)
{
return X.gia < Y.gia;
}
Trang 8Dữ liệu vào: Từ tệp văn bản BAI3.INP gồm:
- Dòng đầu chứa số nguyên dương n (1 ≤ n ≤ 105) (số lượng các nhóm học sinh)
- Dòng số 2 chứa dãy số nguyên dương S 1 , S 2 , … S n (1 ≤ Si ≤ 4) Các số nguyêncách nhau bởi dấu cách với Si là số học sinh trong nhóm thứ i
Dữ liệu ra: Ghi ra tệp văn bản BAI3.OUT là một số nguyên duy nhất là số
lượng tối thiểu xe taxi cần thiết để chở tất cả các học sinh đến nơi
Ví dụ:
Trang 91 2 4 3 3
Ý tưởng: Để giảm chi phí cần tính toán làm sao để cần thuê số lượng xe là ít
nhất thì ta sử dụng kĩ thuật tham lam, dựa vào nhận xét sau để suy ra số lượngxe:
- Nhóm 4 người không đi chung với nhóm nào Suy ra số lượng nhóm 4người = số lượng xe taxi cần gọi
- Nhóm 3 người chỉ có thể đi chung với nhóm 1 người Suy ra số lượngnhóm 3 người= số lượng xe taxi cần gọi
- Nhóm 2 người có thể ghép với nhau Suy ra số lượng xe cần gọi = sốlượng nhóm 2 người chia lấy phần nguyên cho 2
- Nhóm 1 người ghép với nhóm 3 người, số còn lại ghép cứ 4 nhóm vớinhau, số dư nếu là 3 thì đi chung 1 xe, dư 2 hoặc 1 thì ghép với nhóm 2người ở trên
Thuật toán đề xuất
Trang 10Một ngày rảnh rỗi, Mr.Bean chơi trò chơi với những con số Mr Bean lấymột số nguyên dương N rồi thực hiện không giới hạn số lần thao tác “Chọn mộtchữ số X trong số nguyên dương N rồi giảm N đi X đơn vị” Hỏi Mr.Bean phảithực hiện ít nhất bao nhiêu thao tác như vậy để giảm số N về 0.
Ví dụ: N=27, Mr.Bean sẽ thực hiện 5 thao tác để biến đổi là
Dữ liệu: Dòng 1: Một số nguyên duy nhất N (1≤N≤106)
Kết quả: Một dòng duy nhất ghi số thao tác ít nhất để biến đổi N về số ).
Ví dụ:
Ý tưởng: Dễ dàng chứng minh được số thao tác là hữu hạn Khi đó để N thực
hiện thao tác để về giá trị 0 một cách nhanh chóng thì áp dụng kĩ thuật tham lam
ở đây là N luôn trừ cho chữ số có giá trị lớn nhất của N
Thuật toán đề xuất:
Trang 11có nhiều cách tổ chức thực hiện công việc tính toán này, mỗi cách đòi hỏi chiphí thời gian nhất định Chẳng hạn cần tính tổng các số 10, 11, 12, 13 Ta có thểthực hiện lần lượt 10 +11 (mất chi phí 1.05), kết quả thu được đem cộng với 12(mất chi phí là 1.65) và cuối cùng cộng với 13 ( mất chi phí là 2.3) Như vậytổng chi phí phí cộng theo cách này là: 1.05 + 1.65 +2.3=5 Một cách cộng kháclà: 10+11 ( chi phí là 1.05), 12+13 (chi phí là 1.25), cuối cùng cộng hai kết quả
đó với nhau (chi phí là 2.3) Như vậy theo cách thứ hai này tổng chi phí là:1.05+1.25+2.3=4.6
Yêu cầu: Cho dãy N số nguyên dương Cần tìm cách tính tổng của các số này
với tổng chi phí thời gian là nhỏ nhất
Dữ liệu vào: Đọc từ file SUMATION.INP
Dòng đầu tiên chứa số nguyên dương N (2≤N≤ 15000)
Dòng thứ hai ghi N số nguyên dương mà ta cần tính tổng, hai số cách nhau bởi một dấu cách
Dữ liệu ra: Ghi vào file SUMATION.OUT tổng chi phí thời gian thực
hiện nhỏ nhất theo cách tính tổng tìm được Kết quả ghi ra lấy 2 chữ số phần thập phân
Ý tưởng: Sử dụng kĩ thuật tham lam như sau:
Bước 1: Tính tổng 2 phần tử nhỏ nhất của dãy (loại bỏ 2 phần tử đó ra khỏi dãy)
suy ra chi phí tính tổng
Bước 2: Nếu dãy chỉ còn 1 phần tử thì dừng thuật toán
Bước 3: Đưa tổng vừa tính được ở bước 1 vào dãy và lặp lại Bước 1.
Để lấy hai giá trị nhỏ nhất và đưa tổng của chúng vào dãy với thời gian cho phép
có thể sử dụng cấu trúc dữ liệu priority_queue (hang đợi ưu tiên) trong C++
Trang 12Thuật toán đề xuất:
Có hai đội cờ vua A và B thi đấu với nhau Mỗi đội cờ cử ra n kỳ thủ, mỗi
kỳ thủ của đội B chỉ dấu một trận và chỉ đấu với một kỳ thủ của đội A và ngượclại Vậy có tất cả n trận đấu Đội nào thắng được 2 điểm, hoà được 1 điểm vàthua được 0 điểm
Cho đội B được quyền chọn cặp thi đấu
Yêu cầu:
Lập trình để đội B chọn dược các cặp thi đấu sao cho tổng số điểm của đội B làcao nhất, Cho biết trình đội của cầu thủ thứ i của đội A và B lần lượt là a[i] vàb[i] (i=1,2,…,n) và giả sử trong thi đấu, hai kỳ thủ có trình độ ngang nhau sẽhoà và kỳ thủ nào có trình độ cao hơn sẽ thắng
Dữ liệu:
Ghi trên file văn bản CHESS.INP gồm n+1 dòng:
Dòng đầu tiên ghi số nguyên dương n, 1 ≤ n ≤ 1000
Trang 13 Dòng thứ i+1 ghi 2 số nguyên a[i], b[i] (1 ≤ a[i], b[i]≤100) cách nhau ítnhất một khoảng trắng.
Ý tưởng: Sắp xếp dãy A tăng dần; sắp xếp dãy B tăng dần.
Chiến lược tham lam trong bài này là: tìm cách ghép B sao cho số điểm của độithắng đội A để được 2 điểm Sau đó tìm cách ghép cho B còn lại hòa A
Thuật toán đề xuất:
for (int i=1; i<=n; i++)
cin >> a[i] >> b[i];
Trang 14Tìm số nguyên dương K nhỏ nhất sao cho tích các chữ số của K bằng số nguyên
M cho trước
Nếu không tìm được K, in ra -1
Input: file find.inp gồm:
- Một số nguyên M (0 ≤ M ≤ 109)
Output: Ghi ra file find.out gồm:
- Số nguyên dương K là kết quả của bài toán
- Nếu không tìm được K, in ra -1
Ta luôn chứng minh được rằng trong dãy này không thể chứa số 1
Trong bài này ta sẽ áp dụng chiến lược tham lam như sau: muốn x1x2 x nmin thì
ta sẽ sắp xếp thành dãy x1≤ x2≤ ≤ x n Ta sẽ có 2 hướng để tham lam
-Tham lam xét dãy từ trái sang phải để tìm các số từ x1, x2, x n càng nhỏ càngtốt
Xét ví dụ k=12 Nếu xét từ trái sang ta sẽ được số 2*2*3=12, nhưng 223>26(test đề bài) rất nhiều Vì vậy việc tham lam xét từ trái sang phải trong trườnghợp này là không đúng
-Tham lam xét từ bên phải sang để tìm từ x n , , x2, x1càng to càng tốt
* Ok=false// biến này kiểm tra xem có chia hết cho số nào từ 9 2 haykhông Nếu không chia hết thì số đó không tồn tại