SỞ GD&ĐT NGHỆ AN
TRƯỜNG THPT CON CUÔNG
………………………
SÁNG KIẾN KINH NGHIỆM
NÀ M
TÊN ĐỀ TÀI:
PHƯƠNG PHÁP QUY HOẠCH ĐỘNG VÀ ỨNG DỤNG VÀO GIẢI MỘT SỐ BÀI TOÁN BỒI DƯỠNG HỌC SINH GIỎI, THI CHUYÊN BẰNG NGÔN NGỮ LẬP TRÌNH PASCAL VÀ C++
Nhóm tác giả:
1. Đặng Văn Hảo
2. Ngô Thị Thanh Huyền
3. Phan Thị Thuý An
Lĩnh vực: Tin học
Đơn vị: Trường THPT Con Cuông
2
Con Cuông - Năm 2022
MỤC LỤC
Phần I. Đặt vấn đề: ................................................................................................. 5 1. Lí do chọn đề tài ................................................................................................. 5
2. Mục đích nghiên cứu, đóng góp mới của đề tài ............................................... 5 3. Đối tượng nghiên cứu .......................................................................................... 6 4. Phương pháp nghiên cứu ................................................................................... 6 5. Phạm vi nghiên cứu ............................................................................................ 6 6. Cấu trúc của đề tài .............................................................................................. 6
1. Cơ sở lý luận ................................................................................................... 6 2. Cơ sở thực tiễn ................................................................................................ 6 Phần II. Nội dung: ................................................................................................... 7 1. Cơ sở lý luận......................................................................................................... 7 1. 1. Giới thiệu .................................................................................................... 7
1. 2. Phương pháp quy hoạch động .................................................................... 7 1.2.1. Khái niệm ............................................................................................. 7 1.2.2. Đặc điểm chung của phương pháp quy hoạch động ............................. 9 1.2.3. Các bước giải bài toán bằng quy hoạch động ....................................... 9
1. 3. Cách tiếp cận quy hoạch động .................................................................... 9 1. 4. Lớp các bài toán được giải bằng quy hoạch động ..................................... 9 1. 5. Ưu điểm và hạn chế của quy hoạch động ................................................. 10 1.5.1. Ưu điểm ............................................................................................... 10 1.5.2. Hạn chế................................................................................................ 10
2. Cơ sở thực tiễn ................................................................................................... 10 2.1. Thực trạng của vấn đề trước khi áp dụng đề tài ........................................ 11 2.1.1. Đặc điểm tình hình .............................................................................. 11 2.1.2. Thực trạng trước khi nghiên cứu ........................................................ 11 2.1.3. Các giải pháp giải quyết vấn đề .......................................................... 12
2.2. Rèn luyện kỹ năng vận dụng phương pháp Quy hoạch động để giải một số bài toán cơ bản đến nâng cao ........................................................................... 12 2.2.1. Bài toán 1. Tìm dãy con không giảm nhiều phần tử nhất ................... 12 2.2.2. Bài toán 2. Dãy con chung dài nhất ................................................... 15 2.2.3. Bài toán 3. dãy con có tổng bằng s ..................................................... 19
2.2.4. Bài toán 4. chia kẹo ............................................................................. 23 3
2.2.5. Bài toán 5: Xếp đồ vật vào ba lô (mỗi vật có số lượng hạn chế) ........ 27
2. 3. Hướng dẫn giải một số bài toán bằng quy hoạch động ............................ 32 2.3.1. Bài toán 1. xâu con chung dài nhất ..................................................... 32 2.3.2. Bài toán 2. Cho thuê máy .................................................................... 33 2.3.3. Bài toán 3. Rô bốt ............................................................................... 35 2.4. Một số bài toán áp dụng phương pháp quy hoạch động tự giải ............... 36
2.4.1. Bài 1: Tổng lớn nhất ........................................................................... 36 2.4.2. Bài toán 2: Phân tích ........................................................................... 37 2.4.3. Bài toán 3: Bố trí phòng họp ............................................................... 38 2.4.4. Bài toán 4: Nối điểm ........................................................................... 38 2.4.5. Bài toán 5: Tính tổng của dãy số ........................................................ 39
2.4.6. Bài toán 6: Dãy Con lớn nhất đan dấu ................................................ 40 2.4.7. Bài toán 7: Sắp xếp xâu ...................................................................... 40 2.4.8. Bài toán 8: Tìm mật khẩu .................................................................... 41 2.4.9. Bài toán 9: TWOVALS ...................................................................... 41 2.5. So sánh kết quả trước và sau khi áp dụng phương pháp Quy hoạch động vào việc bồi dưỡng ........................................................................................... 42 2.5.1. Trước khi áp dụng phương pháp Quy hoạch động vào việc bồi dưỡng học sinh giỏi .................................................................................................. 42 2.5.2. Sau khi áp dụng phương pháp Quy hoạch động vào việc bồi dưỡng học sinh giỏi .................................................................................................. 43 Phần III. Kết luận: ................................................................................................ 45
1. Kết Luận ............................................................................................................. 45 1.1 Với mục tiêu đặt ra đề tài đã làm được: .................................................... 45 1.2. Hướng phát triển của đề tài: ..................................................................... 45 2. Một số kiến nghị đề xuất .................................................................................. 46 TÀI LIỆU THAM KHẢO .................................................................................... 47
4
PHỤ LỤC ............................................................................................................... 48
Phần I. Đặt vấn đề
1. Lí do chọn đề tài
Tự học tập, nghiên cứu là một nhiệm vụ quan trọng của mỗi giáo viên để nâng cao trình độ chuyên môn, phục vụ cho công tác giảng dạy và đặc biệt là trong bồi dưỡng đội tuyển học sinh giỏi.
Trong những năm gần đây, trong các đề thi học sinh giỏi tỉnh, quốc gia cũng như các bài tập trên các trang giải bài trực tuyến vn.spoj.com, vnoi.info, … có nhiều bài tập nếu chúng ta sử dụng những kiến thức cơ bản như đệ quy, duyệt, chia để trị, … có thể giải quyết được nhưng gặp nhiều khó khăn về mặt tốc độ cũng như giới hạn dữ liệu. Trong khi đó nếu chúng ta sử dụng phương pháp quy hoạch động hoặc các phương pháp trên có kết hợp với quy hoạch động thì cho một hiệu quả cao.
Quy hoạch động là một phương pháp rất hiệu quả để giải lớp bài toán trong Tin học. Đặc biệt là những bài toán tối ưu, khi sử dụng phương pháp quy hoạch động chương trình chạy nhanh, cách viết chương trình rõ ràng. Nhưng không phải bài toán nào cũng có thể áp dụng được bằng phương pháp quy hoạch động. Vậy thường những bài toán như thế nào thì áp dụng được phương pháp quy hoạch động và cách giải một bài toán quy hoạch động như thế nào là một vấn đề?
Mặt khác hiện nay khi bồi dưỡng thi học sinh giỏi giáo viên có thể lựa chọn 1 trong 3 ngôn ngữ lập trình là Pascal, C++ hoặc là Python. Pascal là ngôn ngữ lập trình đã cũ, câu lệnh dài và không được hỗ trợ nhiều. Python là ngôn ngữ lập trình mới nhất, câu lệnh ngắn gọn, hỗ trợ nhiều trong khi viết chương trình. Tuy nhiên một số bài toán khi chạy chương trình còn hạn chế về mặt thời gian. Chính vì vậy hiện nay thi học sinh giỏi thì ngôn ngữ lập trình C++ được lựa chọn nhiều nhất. Cho nên trong đề tài này tôi sử dụng ngôn ngữ lập trình C++ để viết chương trình cũng như minh hoạ thuật toán. Ngoài ra tôi còn minh hoạ chương trình bằng ngôn ngữ lập trình Pascal (Link code minh hoạ bằng ngôn ngữ lập trình pascal để ở phần phụ lục của đề tài) cho một số bạn đọc dễ hiểu và nắm bắt tốt hơn khi chưa tiếp cận nhiều với ngôn ngữ lập trình C++.
Vì những lý do trên, với những kinh nghiệm và tìm hiểu của bản thân, tôi đưa ra đề tài “phương pháp quy hoạch động và ứng dụng vào giải một số bài toán bồi dưỡng học sinh giỏi, thi chuyên bằng ngôn ngữ lập trình Pascal và C++” .
2. Mục đích nghiên cứu, đóng góp mới của đề tài
- Đề tài nêu ra các định hướng giúp học sinh có thể tiếp cận phương pháp Quy
hoạch động để giải một số bài toán tối ưu phù hợp với dữ liệu bài toán.
- Giúp người đọc tiếp cận ngôn ngữ lập trình C++ tốt hơn trong khi lập trình.
5
- Từ đó bồi dưỡng học sinh năng lực giải quyết vấn đề trong giải toán Tin học, đồng thời rèn luyện và nâng cao kĩ năng lập trình cho các em. Đặc biệt là học sinh
tham gia dự thi học sinh giỏi cấp tỉnh THCS, THPT, thi Olimpic Tin học trẻ hoặc thi vào các trường chuyên.
- Đối tượng nghiên cứu là học sinh giỏi tin, giáo viên giảng dạy, bồi dưỡng
3. Đối tượng nghiên cứu
- Phương pháp quy hoạch động và các bài toán tối ưu.
học sinh giỏi môn Tin trong trường THCS và THPT.
4. Phương pháp nghiên cứu
Để hoàn thành nhiệm vụ, tôi đã nghiên cứu rất nhiều sách và các chuyên đề Tin học dành cho học sinh Chuyên tin, những vấn đề cơ bản nhất về cấu trúc dữ liệu, thuật toán và cài đặt chương trình.
Cùng nhau trao đổi, thảo luận, rút kinh nghiệm cùng các đồng nghiệp trong
và ngoài trường nhằm nâng cao chất lượng cho đề tài.
Lựa chọn một số bài toán giải bằng phương pháp Quy hoạch động trong các
đề thi và chương trình tin học chuyên THPT.
5. Phạm vi nghiên cứu
Lí thuyết về Quy hoạch động và một số bài tập ứng dụng kĩ thuật xử lí Quy hoạch động hiệu quả trong các đề thi học sinh giỏi, các bài tập trên các trang trực tuyến như: vn.spoj.com, vnoi.info, laptrinh.ntu.edu.vn, chuyentin.pro…
6. Cấu trúc của đề tài
Ngoài phần mở đầu, kết luận và kiến nghị, phần nội dung đề tài gồm có 2
nội dung:
1. Cơ sở lý luận
Giới thiệu về phương pháp Quy hoạch động, các bước tiếp cận với phương pháp Quy hoạch động, cách nhận diện xem bài toán tối ưu nào có thể giải bằng phương pháp Quy hoạch động và nếu giải thì cách giải như thế nào? Trình bày các dạng, phân tích và cài đặt chương trình cụ thể để bạn đọc dễ hiểu nhất. Qua đó có thể vận dụng để giải quyết các bài toán về sau.
2. Cơ sở thực tiễn
6
Nêu ra thực trạng vấn đề, những hạn chế, khó khăn của học sinh cũng như giáo viên trong việc giải quyết các bài toán lớn, các bài toán ôn thi học sinh giỏi hiện nay. Qua đó giải quyết vấn đề và đưa ra các bài toán điển hình để so sánh sử dụng phương pháp Quy hoạch động và một số phương pháp khác. Sử dụng phương pháp Quy hoạch động có thể vận dụng lập trình giải các bài toán trong các đề thi hay khi ôn luyện. Trang bị kiến thức cho học sinh và giáo viên để giải quyết tốt khi gặp các bài toán có liên quan đến sử dụng phương pháp Quy hoạch động một cách hiệu quả nhất.
Phần II. Nội dung:
1. Cơ sở lý luận
Giới thiệu về phương pháp Quy hoạch động, các bước tiếp cận với phương pháp Quy hoạch động, cách nhận diện xem bài toán tối ưu nào có thể giải bằng phương pháp quy hoạch động và nếu giải thì cách giải như thế nào? Trình bày các dạng, phân tích và cài đặt chương trình cụ thể để bạn đọc dễ hiểu nhất. Qua đó có thể vận dụng để giải quyết các bài toán về sau.
1. 1. Giới thiệu
Phương pháp quy hoạch động do nhà toán học người Mỹ Richard Bellman
(1920 – 1984) phát minh năm 1953.
Phương pháp quy hoạch động (dynamic programming) là một kỹ thuật được
áp dụng để giải nhiều lớp bài toán, đặc biệt là bài toán tối ưu.
Vậy bài toán tối ưu là gì?. Đó chính là bài toán có nhiều nghiệm chấp nhận được mỗi nghiệm có một giá trị đánh giá. Mục tiêu đặt ra là tìm nghiệm tối ưu, đó là nghiệm có giá trị đánh giá nhỏ nhất hoặc lớn nhất (tối ưu).
Khi tiến hành giải một bài toán phức tạp (bài toán lớn) ban đầu người ta thường đi chia bài toán đó thành các bài toán con độc lập đơn giản để giải, khi tiến hành giải xong các bài toán con ta tổng hợp lời của các bài toán con và đó chính là bài toán lớn cần giải. Đây chính là phương pháp chia để trị được sử dụng rất thông dụng trong quá trình lập trình giải các bài toán trong Tin học. Nhưng đối với những bài toán phức tạp nếu chúng ta sử dụng phương pháp này thì sẽ mất test ở những dữ liệu lớn. Vì chưa tối ưu về mặt thời gian. Chính vì vậy phương pháp Quy hoạch động ra đời nhằm cải tiến về vấn đề này.
1. 2. Phương pháp quy hoạch động
1.2.1. Khái niệm
Phương pháp quy hoạch động là một kỹ thuật nhằm đơn giản hóa việc tính toán các công thức truy hồi bằng cách lưu toàn bộ hay một phần kết quả tính toán của mỗi bước trước đó với mục đích sử dụng lại (Công thức truy hồi là công thức thể hiện quan hệ giữa các bước trong một bài toán và kết quả của các bước sau thường dựa vào kết quả của các bước trước đó. Kết quả của bước cuối cùng chính là kết quả bài toán cần tìm).
Vậy bản chất của quy hoạch động =Chia để trị+Mảng (Lưu lại kết quả)
7
Phương pháp quy hoạch động sử dụng nguyên lý bottom - up, nghĩa là “ đi từ dưới lên”. Đầu tiên ta phải giải các bài toán con đơn giản nhất, có thể tìm ngay ra nghiệm. Sau đó kết hợp các bài toán con này lại để tìm lời giải cho bài toán lớn hơn và cứ như thế cho đến khi giải được bài toán yêu cầu. với phương pháp này mỗi bài toán con sau khi giải xong đều được lưu trữ lại và đem ra sử dụng nếu cần. Khi đó sẽ tiết kiệm được bộ nhớ và thời gian thực hiện.
Ngược lại phương pháp đệ quy giải quyết bài toán theo hướng top – down, nghĩa là để giải bài toán ban đầu, ta phải đi giải các bài toán con của nó. Đây là một phương pháp hay, tuy nhiên phương pháp này sẽ gặp một số hạn chế về mặt thời gian , tốc độ do phải tính toán nhiều lần một số bài toán con giống nhau nào đó. Để thấy rõ hơn ta đi tìm hiểu ví dụ sau:
Xét ví dụ 1: dãy Fibonacci là dãy số nguyên sau:
F0= 1, F1= 1,
Fn = Fn-1+Fn-2 với mọi n>=2
Hãy tính F5
Cách 2 Cách 1
#include
main() int f(int n)
{ {
int i,f[10]; int t;
f[1]=f[0]=1; if (n<2) return 1;
else return f(n-1)+f(n-2);
for(i=2;i<=5;i++) f[i]=f[i-1]+f[i-2];
cout<<"fib thu 5 la "< getch(); main() } { int n; cout<<"fib thu 5
la"< } 8 Cách 1: viết hàm đệ quy f(n) để tính số Fibonacci thứ n. Chương trình chính
gọi f(5) nó sẽ gọi đến f(4) và f(3) để tính… quá trình tính toán có thể vẽ như cây
sau : Như vậy để tính được f(5) máy tính phải thực hiện mất 1 lần f(4), 2 lần f(3), 3
lần f(2), 2 lần f(1). Nhưng cách 2 thì không như vậy nó tính f(1), f(2) từ đó tính
f(3), và tính được f(4), f(5). Khi đó mỗi giá trị chỉ phải tính một lần và cần lấy f[i]
nào thì lấy ra. - Quy hoạch động bắt đầu từ việc giải tất cả các bài toán nhỏ nhất (bài toán cơ
sở) để từ đó từng bước giải quyết bài toán lớn hơn cho tới khi giải được bài toán
lớn nhất là bài toán ban đầu. - Quy hoạch động cần có bảng phương án: chính là không gian lưu trữ lời giải
các bài toán con để tìm cách phối hợp chúng, đây là bảng phương án của quy
hoạch động. Thường kết quả cuối cùng của bảng phương án chính là kết quả của
bài toán cần tìm. 1.2.2. Đặc điểm chung của phương pháp quy hoạch động 1.2.3. Các bước giải bài toán bằng quy hoạch động Bước 1: Giải tất các bài toán cơ sở (thường là dễ nhất). lưu các lời giải vào bảng phương án. Đây là điều kiện dừng của bài toán Bước 2: Xây dựng công thức truy hồi : bằng cách phối hợp những lời giải của
bài toán nhỏ hơn đã lưu trong bảng phương án để tìm lời giải của bài toán lớn hơn
(công thức truy hồi) và lưu vào bảng phương án, nhờ có công thức truy hồi này ta
tính được bảng phương án. Bước 3: Dựa vào bảng phương án, ta truy vết tìm nghiệm tối ưu. Đây chính là kết quả của bài toán. 1. 3. Cách tiếp cận quy hoạch động Quy hoạch động thường dùng một trong 2 cách tiếp cận sau : - Tiếp cận từ dưới lên (Bottom up) Là phương pháp đi từ cái riêng đến cái chung, từ các thành phần ở mức cao
tới các đối tượng thành phần ở mức thấp, từ mức đơn vị chương trình tới mức tổng
thể. - Tiếp cận từ trên xuống ( Top down) Là phương pháp phân rã vấn đề có hệ thống từ trên xuống. Cách tiếp cận từ dưới lên hiệu quả hơn từ trên xuống nên cách tiếp cận từ dưới lên được sử dụng nhiều hơn. 1. 4. Lớp các bài toán được giải bằng quy hoạch động Nhưng không phải bài toán tối ưu nào cũng giải được bằng phương pháp quy - Khi bài toán có tính chất truy hồi. 9 hoạch động. Thường những bài toán có đặc điểm sau: - Bài toán lớn phải phân rã được thành nhiều bài toán con, mà sự phối hợp lời giải của các bài toán con đó cho ta lời giải của bài toán lớn. - Có thể lưu trữ nghiệm của các bài toán con dưới một hình thức nào đó để - Quá trình từ bài toán cơ sở tìm ra lời giải bài toán ban đầu phải qua hữu hạn phối hợp tìm nghiệm của bài toán lớn. - Kích thước của bài toán lớn. bước. 1. 5. Ưu điểm và hạn chế của quy hoạch động - Qua phân tích ở ví dụ 1 ta thấy được ưu điểm của quy hoạch động là tiết
kiệm được thời gian thực hiện vì không cần phải tính đi tính lại nhiều lần một số
bài toán con giống nhau. - Ngoài ra lời giải của bài toán sử dụng quy hoạch động thường gắn gọn, sáng 1.5.1. Ưu điểm sủa, có tính chất lời giải cao. - Việc tìm công thức truy hồi không phải dễ tìm. Để tìm được đòi hỏi sự phân
tích tổng hợp rất công phu, khó nhận ra được như thế nào là chính xác nên mất
nhiều thời gian để suy nghĩ. - Khi lưu bảng lưu trữ đòi hỏi mảng hai chiều, ba chiều…thì khó có thể xử lý
dữ liệu với kích thước cỡ mỗi chiều lớn đến hàng trăm. Và còn bị hạn chế về bộ
nhớ vì ta phải lưu trữ nghiệm của các bài toán con. - Không phải lúc nào kết hợp lời giải các bài toán con cũng được kết quả của
bài toán lớn mà ta còn phải biết sử dụng và phối hợp uyển chuyển nhiều thuật toán,
không được lạm dụng hay coi thường bất cứ một phương pháp nào. - Có những bài toán không thể giải được bằng quy hoạch động. 1.5.2. Hạn chế 2. Cơ sở thực tiễn 10 Nêu ra thực trạng vấn đề, những hạn chế, khó khăn của học sinh cũng như
giáo viên trong việc giải quyết các bài toán lớn, các bài toán ôn thi học sinh giỏi
hiện nay. Qua đó giải quyết vấn đề và đưa ra các bài toán điển hình để so sánh sử
dụng phương pháp Quy hoạch động và một số phương pháp khác. Sử dụng phương
pháp Quy hoạch động có thể vận dụng lập trình giải các bài toán trong các đề thi
hay khi ôn luyện. Trang bị kiến thức cho học sinh và giáo viên để giải quyết tốt khi
gặp các bài toán có liên quan đến sử dụng phương pháp Quy hoạch động một cách
hiệu quả nhất. 2.1. Thực trạng của vấn đề trước khi áp dụng đề tài 2.1.1. Đặc điểm tình hình * Thuận lợi: - Với sự bùng nổ của ngành công nghệ thông tin cũng như chương trình giáo dục phổ thông 2018 các em học sinh, phụ huynh ngày càng quan tâm hơn. - Ngày nay số lượng học sinh có máy tính cá nhân ngày càng nhiều, các em có điều kiện để học tập, nghiên cứu và lập trình được nhiều hơn. - Các cuộc thi lập trình này ngày càng tổ chức nhiều hơn, việc học, xem tài
lệu cũng dễ dàng hơn, có thể xem các tài liệu trên web cũng như các kênh như
youtube…. * Khó khăn: - Do môn Tin học chưa có trong tổ hợp môn thi tốt nghiệp và đại học nên
các em và phụ huynh chưa quan tâm đến nên việc chọn học sinh giỏi cũng như
các em chưa thực sự đầu tư chuyên sâu vào lập trình. - Những kiến thức trong chương trình Tin học phổ thông còn hạn chế, hoặc
chưa đủ đáp ứng cho việc giải một số bài toán trong các kỳ thi học sinh giỏi
Tỉnh khi có yêu cầu dữ liệu lớn cùng thời gian thực hiện ngắn. - Các tài liệu tổng hợp các cách để giải quyết các bài toán yêu cầu cao như vậy chưa có nhiều để học sinh tham khảo, ôn luyện. 2.1.2. Thực trạng trước khi nghiên cứu Ngày nay công nghệ thông tin là một trong những ngành hót, nhân lực còn
thiếu, mỗi năm sinh viên ra trường chưa đáp ứng đủ yêu cầu thị trường, mức thu
nhập nghành công nghệ thông tin là khá cao, nên việc quan tâm của các em ngày
càng nhiều, nhất là trong các cuộc thi lập trình. Năm học này thì trường đại học và khoa học công nghệ Hà Nội đã có 9 ngành cho học sinh đăng kí thi tổ hợp môn: Toán , Lý, Tin Với sự phát triển nhanh về tốc độ cũng như sự quan tâm đến của nghành công
nghệ thông tin ngày càng cao thì đề thi học sinh giỏi Tin học cũng đòi hỏi ngày càng
nâng cao hơn. Trong các đề thi học giỏi thì người ta quan tâm về thời gian thực
hiện và độ lớn của dữ liệu đầu vào. Đa số giáo viên gặp khó khăn trong việc hướng
dẫn học sinh giải bài toán thế nào để đạt được trọn vẹn yêu cầu của bài toán. 11 Đối với những bài toán phức tạp và có dữ liệu lớn thì giáo viên và học sinh
còn gặp khó khăn, chưa giải quyết vấn đề một cách triệt để. Dẫn đến sẽ mất test.
Chương trình chưa tối ưu chỉ ăn test với dữ liệu nhỏ. 2.1.3. Các giải pháp giải quyết vấn đề Có những bài toán nhiều khi có vẻ đơn giản, đa số học sinh có thể giải được
nhưng khi thực hiện với dữ liệu lớn thì không đáp ứng được thời gian yêu cầu hoặc
không thể thực hiện được tất cả các test yêu cầu. Lúc này đòi hỏi phải tìm được thuật
toán tối ưu nhất. Đa số khi chấm bài, dùng test chấm mới biết được chương trình đáp ứng được
bao nhiêu test so với yêu cầu của đề ra. Điều này chỉ thực hiện được khi ôn luyện
cho các em, còn khi các em đi thi thì không tự ước lượng được bài làm đạt kết quả
thế nào. Thuật toán Quy hoạch động không gì khác hơn là một sự tối ưu hóa của các
kỹ thuật. Nó làm giảm sự phức tạp về thời gian bằng cách sử dụng một số loại thứ
tự thay vì nhất thiết phải sắp xếp dữ liệu. Qua đó giúp chương trình chạy nhanh
hơn, không gian lưu trữ ít hơn. Hiện nay trong các kì thi học sinh giỏi và thi vào trường chuyên, đề thi
thường có những bài toán mà sử dụng phương pháp Quy hoạch động để giải quyết
vấn đề mới tối ưu. Chính vì vậy giáo viên và học sinh nắm rõ phương pháp Quy
hoạch động là một lợi thế rất lớn khi lập trình giải những bài toán phức tạp và dữ
liệu lớn. Như vậy sẽ đạt kết quả cao hơn trong các kì thi học sinh giỏi nói chung và
thi vào trường chuyên nói riêng Và trong đề tài này tôi đã trình bày các kiến thức và kĩ năng từ đó vận dụng
phương pháp Quy hoạch động để xử lý những bài toán như vậy. Sau khi đọc hiểu
về mặt lý thuyết thì người đọc có thể thực hành làm những bài tập điển hình có
code, có hướng dẫn. Qua đó sẽ tự tin hơn, tư duy và kỹ năng tốt hơn, nắm rõ và có
thể vận dụng để lập trình giải những bài toán cùng dạng sau này. 2.2. Rèn luyện kỹ năng vận dụng phương pháp Quy hoạch động để giải một số
bài toán cơ bản đến nâng cao 2.2.1. Bài toán 1. Tìm dãy con không giảm nhiều phần tử nhất Cho dãy số nguyên có n phần tử a1, a2, ..., an . Một dãy con không giảm của
dãy đã cho là dãy các phần tử còn lại của dãy đó sau khi ta xóa bỏ một hoặc một số
phần tử bất kì của nó, các phần tử của dãy con tạo thành không giảm. Ví dụ: dãy 1,
4, 10, 11, 12 là một dãy con không giảm của 1, 4, 10, 9, 8, 17, 11, 7, 12, 6. * Yêu cầu: Tìm dãy con không giảm của dãy a gồm nhiều phần tử nhất. * Dữ liệu vào: từ file văn bản DAYCON.INP gồm 2 dòng: - Dòng tiếp theo, ghi các số nguyên của dãy N số nguyên a1, a2,...,an - Dòng đầu tiên ghi số N (0 12 mỗi số cách nhau một dấu cách. - Số max là độ dài dãy con không giảm dài nhất tìm được - Chỉ số xuất hiện của các số hạng của dãy con trong dãy đã cho. * Kết quả: ghi ra file văn bản DAYCON.OUT gồm 2 dòng: * Ví dụ: DAYCON.INP DAYCON.OUT 10 5 6 5 8 12 6 9 7 13 2 13 6 8 12 13 13 *Cách giải: Gọi l[i] là độ dài dãy con không giảm dài nhất, các phần tử lấy trong miền từ an đến ai và phần tử bắt đầu là a[i] (i=n, n-1,..., 0). Bài toán sử dụng thêm 2 phần tử: a[0]= -32768 và a[n+1]=32767 chắc chắn
thuộc dãy con không giảm dài nhất. Khi đó độ dài dãy con không giảm dài nhất bắt
đầu từ a[n+1] là 1, dãy bắt đầu từ a[i], ..., a[n+1]; Bước 1: Giải các bài toán cơ sở và lưu vào bảng phương án L[n+1]=1; với a[n+1]=32767 nên chắc chắn thuộc dãy con không giảm dài nhất. Bước 2: Tìm công thức truy hồi Khi xét tới phần tử a[i] thì a[i] phải nối vào đầu 1 dãy con không giảm mà bắt đầu phần tử a[j] nào đó phải thõa mãn a[i]<=a[j] (j=i+1,...,n+1). Nhưng trong đó các a[j]>=a[i] thì ta phải chọn jmax để dãy con không giảm bắt đầu từ a[jmax] dài nhất. Nên công thức truy hồi của bài toán là: L[i]=max{l[j] | j=i+1,..., n+1 thõa mãn a[i]<=a[j]} +1 Bước 3: Dựa vào bảng phương án, ta truy vết tìm nghiệm tối ưu. * Tính bảng phương án: dựa vào giá trị l[n+1]=1 để tính tiếp l[i] (i= n, n- 1,...,0). Dùng t[i] để lưu lại các vị trí jmax. Xét ví dụ: N=10; a=(6 5 8 12 6 9 7 13 2 13) ta có bảng phương án 1 2 3 4 5 6 7 8 9 10 11 I 0 5 8 12 6 9 7 13 2 13 32767 A -32768 6 6 6 5 4 5 4 4 3 3 2 1 L 7 13 3 3 6 8 6 8 8 10 9 10 11 T 1 Đoạn code tính l[i] như sau: l[n+1]=1; t[n+1]=n+1; for (int i=n;i>=0;i--) { jmax=n+1; for (int j=i+1;j<=n+1;j++) if ((a[i]<=a[j])&&(l[j]>l[jmax])) jmax=j; l[i]=l[jmax]+1; t[i]=jmax; }
* Độ phức tạp của thuật toán: Với đoạn code trên thì dễ thấy chi phí không gian cài đặt trên là O(n), chi phí thời gian là O(n2). Với n là số phần tử của dãy. * Truy vết tìm ra các phần tử trong dãy: dựa vào mảng t[i] để đưa ra các phần tử thuộc dãy con không giảm dài nhất. Chương trình sau sẽ trình bày cụ thể. Chương trình hoàn chỉnh #include using namespace std; ifstream fi ("DAYCON.INP"); ofstream fo ("DAYCON.OUT"); int n,a[100],l[100],t[100]; void nhap() { fi>>n; a[0]=-32768; a[n+1]=32767; for (int i=1;i<=n;i++)
fi>>a[i]; } void qhd() 14 { int jmax; l[n+1]=1; t[n+1]=n+1; for (int i=n;i>=0;i--) { jmax=n+1; for (int j=i+1;j<=n+1;j++) if ((a[i]<=a[j])&&(l[j]>l[jmax])) jmax=j; l[i]=l[jmax]+1; t[i]=jmax; } } void Truyvet()