SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HOÁ TRƯỜNG THPT LÊ LỢI SÁNG KIẾN KINH NGHIỆM TÊN ĐỀ TÀI: SỬ DỤNG PHƯƠNG PHÁP QUY HOẠCH ĐỘNG VÀ ỨNG DỤNG TRONG VIỆC BỒI DƯỠNG HỌC SINH GIỎI MÔN TIN HỌC Ở TRƯỜ
Trang 1SỞ GIÁO DỤC VÀ ĐÀO TẠO THANH HOÁ
TRƯỜNG THPT LÊ LỢI
SÁNG KIẾN KINH NGHIỆM
TÊN ĐỀ TÀI:
SỬ DỤNG PHƯƠNG PHÁP QUY HOẠCH ĐỘNG VÀ ỨNG DỤNG TRONG VIỆC BỒI DƯỠNG HỌC SINH GIỎI MÔN TIN HỌC Ở TRƯỜNG THPT LÊ LỢI, HUYỆN THỌ XUÂN,
Trang 2THANH HÓA NĂM 2022
MỤC LỤC
1 MỞ ĐẦU .1
1.1 Lý do chọn đề tài 1
1.2 Mục đích nghiên cứu 2
1.3 Đối tượng nghiên cứu 2
1.4 Phương pháp nghiên cứu 2
2 NỘI DUNG SÁNG KIẾN KINH NGHIỆM 2.1 Cơ sở lý luận 2
2.2 Thực trạng của vấn đề … , 3
2.3 Các giải pháp giải quyết vấn đề 3
2.3.1 Các yêu cầu của một bài toán tối ưu sử dụng được trong phương pháp quy hoạch động , 3
2.3.2 Các bước giải bài toán tối ưu bằng phương pháp quy hoạch động 3
2.3.3 Một số bài toán quy hoạch động cơ bản dạy học sinh giỏi THPT 4
2.4 Hiệu quả của SKKN … , 18
3 KẾT LUẬN, KIẾN NGHỊ … , 19
Trang 31.MỞ ĐẦU
1 1 Lí do chọn đề tài
Bồi dưỡng học sinh giỏi là một nhiệm vụ quan trọng đối với mỗi giáo viên
Do đó, việc nghiên cứu, tìm tòi, tích lũy kiến thức là công việc thường nhật củamỗi giáo viên nhằm nâng cao trình độ chuyên môn nghiệp vụ, tích lũy kinh nghiệmcho bản thân
Chúng ta biết rằng, để có kết quả cao trong kì thi tuyển chọn học sinh giỏimôn Tin học nói chung thì học sinh phải có vốn kiến thức về thuật toán để giảiđược các bài toán khó, sau đó học sinh sẽ sử dụng một ngôn ngữ lập trình nào đó
để lập trình dựa vào thuật toán đã tìm được và giải bài toán theo yêu cầu Chươngtrình giảng dạy ở sách giáo khoa của môn Tin học hiện hành trong trường THPT
có lượng kiến thức rất hạn chế và đơn giản, không đủ cơ sở và không thể là nềntảng để học sinh có thể dựa vào vốn kiến thức đó tham gia một kì thi học sinh giỏi
cấp Tỉnh hay cao hơn Câu hỏi đặt ra là: Làm thế nào để học sinh có thể đạt kết
quả cao trong các kì thi học sinh giỏi môn Tin học trong trường THPT?
Xuất phát từ việc trực tiếp bồi dưỡng học sinh giỏi nhiều năm, bản thân tôinhận thấy việc nắm vững các thuật toán và áp dụng nó một cách linh hoạt trong cácbài tập nhất định là không đơn giản Để có thể nhận dạng một bài toán có thể thựchiện với các thuật toán không phải dễ Ngoài ra để cài đặt được thuật toán hiệu quảnhất cũng đòi hỏi người lập trình cần nắm vững các phương pháp thiết kế thuậttoán Đa số học sinh cảm thấy khó khăn khi giải các bài toán tin có liên quan đếnthuật toán nâng cao, rất lúng túng trong quá trình phân tích, tổ chức dữ liệu, tìm rathuật toán hiệu quả Vì vậy, để giúp học sinh tháo gỡ được những khó khăn, vướngmắc trong quá trình học tập, ôn luyện thi học sinh giỏi, thì bản thân tôi khôngngừng học hỏi trước hết là thực hiện đổi mới phương pháp giảng dạy Tin học giúpcho học sinh tìm ra những kết quả sáng tạo, lời giải hay cho các bài toán, giúp bảnthân nắm vững hơn nữa về tư duy thuật toán, khả năng lập trình
Quy hoạch động (Dynamic Programming) là một phương pháp rất hiệu quả
để giải nhiều bài toán tin học, đặc biệt là những bài toán tối ưu, có một số bài toán
sử dụng phương pháp quy hoạch động lại cho hiệu quả cao hơn hẳn so với nhiềuphương pháp khác Số lượng các bài thi có thể áp dụng phương pháp quy hoạchđộng để giải trong đề thi học sinh giỏi môn Tin học thường rất cao
Xuất phát từ những lí do trên, tôi xin trình bày một sáng kiến nhỏ trong công
Trang 4ứng dụng trong việc bồi dưỡng học sinh giỏi môn Tin học ở trường THPT Lê Lợi, huyện Thọ Xuân, tỉnh Thanh Hóa"
Trong quá trình triển khai đề tài, bản thân tôi tự thấy đã có những kết quả nhất định, muốn được chia sẻ với các bạn đồng nghiệp Hi vọng sẽ nhận được nhiều ý kiến bổ ích để đề tài của tôi ngày một hoàn thiện hơn
1.2 Mục đích nghiên cứu:
Áp dụng đề tài này tôi hướng tới những mục đích sau:
- Mục đích chính của đề tài là nghiên cứu về phương pháp Quy hoạchđộng ứng dụng trong bồi dưỡng học sinh giỏi môn tin học khối THPT
- Nâng cao chất lượng bồi dưỡng học sinh giỏi
- Giúp học sinh thêm yêu thích bộ môn Tin học hơn
1.3 Đối tượng nghiên cứu:
- Học sinh khối 11 trường THPT Lê Lợi
- Nghiên cứu khái quát về chương trình môn Tin học 11 nói chung vàphương pháp Quy hoạch động nói riêng
- Một số chuyên đề nâng cao bồi dưỡng học sinh giỏi
- Nghiên cứu hoạt động dạy và học của học sinh và giáo viên trong trườngTHPT
1.4 Phương pháp nghiên cứu:
- Phương pháp điều tra khảo sát thực tế.
- Phương pháp thu thập thông tin
- Phương pháp thống kê, xử lí số liệu, so sánh
Phương pháp quy hoạch động là một kỹ thuật nhằm đơn giản hóa việc tínhtoá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ántại mỗi bước trước đó với mục đích sử dụng lại
Trang 5Điểm khác nhau cơ bản giữa phương pháp quy hoạch động và phương pháp
đệ quy là: Phương pháp đệ quy giải quyết bài toán theo hướng topdown, nghĩa là
để giải bài toán ban đầu, ta phải đi giải tất cả các bài toán con của nó Đây là mộtphương pháp hay, tuy nhiên phương pháp này sẽ gặp hạn chế về mặt thời gian, tốc
độ do phải tính đi tính lại nhiều lần một số bài toán con giống nhau nào đó Cònphương pháp quy hoạch động sử dụng nguyên lý bottom-up, nghĩa là "đi từ dướilên" Đầu tiên, ta sẽ phải giải các bài toán con đơn giản nhất, có thể tìm ngay ranghiệ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ớnhơ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
Do đó tiết kiệm bộ nhớ và cải thiện được tốc độ
2.2 Thực trạng vấn đề trước khi áp dụng sáng kiến kinh nghiệm
- Môn Tin học là môn khoa học tự nhiên không dễ đối với học sinh Hơnnữa, đó là môn không thi tốt nghiệp và đại học nên chưa được học sinh, phụ huynhquan tâm đúng mức Dẫn đến việc tuyển chọn đội tuyển học sinh giỏi gặp nhiềukhó khăn
- Khi chưa áp dụng sáng kiến này thì nếu học sinh gặp các bài toán tối ưucác em thường ít khi sử lý được các bài toán với miền dữ liệu lớn và thường khôngđảm bảo được về mặt thời gian Các em thường lúng túng trong quá trình phân tíchbài toán, tổ chức dữ liệu, tìm ra thuật toán hiệu quả để lập trình giải các bài toán
2.3 Các giải pháp giải quyết vấn đề.
2.3.1 Các yêu cầu của một bài toán tối ưu sử dụng được phương pháp quy hoạch động.
Một bài toán tối ưu muốn giải được bằng phương pháp quy hoạch động khibài toán tối ưu đó có các đặc điểm sau đây:
- 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ợplờ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
- Vì quy hoạch động là đi giải tất cả các bài toán con nên nếu không đủkhông gian vật lý lưu trữ kết quả (bộ nhớ, đĩa…) để phối hợp chúng thìphương pháp quy hoạch động cũng không thể thực hiện được
- Quá trình từ bài bài toán cơ sở tìm ra lời giải bài toán ban đầu phải quahữu hạn bước
2.3.2 Các bước giải bài toán tối ưu bằng phương pháp quy hoạch động.
Bước 1: Phân rã bài toán cần giải thành những bài toán con giống hệt nó
nhưng có kích thước nhỏ hơn
Trang 6Bước 2:
Bước 2.1: Giải bài toán con nhỏ nhất: Là bài toán có thể giải được
trực tiếp (có thể có một bài toán con nhỏ nhất cũng có thể có hai, babài toán con nhỏ nhất)
Bước 2.2: Giải các bài toán con khác dựa vào lời giải của những bài
toán đã biết bằng cách tìm mối liên hệ giữa các bài toán, tức là tìmđược công thức truy hồi - công thức quy hoạch động Lưu lời giải vàobảng phương án
Bước 3: Truy vết, tìm nghiệm của bài toán dựa vào bảng phương án.
2.3.3 Một số bài toán quy hoạch động cơ bản dạy học sinh giỏi THPT.
a) Một số bài toán cơ bản.
Trong đề tài này tôi xin giới thiệu một số bài toán quy hoạch động cơ bản sử dụng trong việc bồi dưỡng học sinh giỏi môn Tin ở trường THPT
Bài toán 1 Dãy con tăng dài nhất.
Cho dãy A gồm n số nguyên: a1, a2, a3,…, an Hãy tìm dãy con tăng dài nhất(không nhất thiết các phần tử phải liên tiếp)
Input: - Dòng 1: chứa số nguyên dương n (1<=n<=1000)
- Dòng 2: chứa n số nguyên dương a1, a2, a3, …, an (1<=ai <=10000)Output: - Dòng 1: chứa độ dài của dãy con tăng dài nhất
- Dòng 2: dãy con tăng dài nhất
Phân tích:
Vì dãy kết quả chưa biết khởi đầu và kết thúc nên ta thêm vào dãy 2 phần tử
kết thúc ở phần tử an+1
Bước 1: Phân rã bài toán cần giải thành những bài toán con giống hệt nó
nhưng có kích thước nhỏ hơn
Để tìm dãy con tăng dài nhất từ a0 đến an+1 ta sẽ đi tìm:
- dãy con tăng dài nhất từ a0 đến a0
- dãy con tăng dài nhất từ a0 đến a1
- dãy con tăng dài nhất từ a0 đến a2.
- …
Tổng quát: Ta cần tìm dãy con tăng dài nhất từ a0 đến ai (với 0<=i<=n+1)
Trang 7Gọi F[i] là độ dài của dãy con tăng dài nhất từ a0 đến ai (với 0<=i<=n+1)
Bước 2
Bước 2.1: Giải bài toán con nhỏ nhất:
bằng 1)
Bước 2.2: Tìm công thức truy hồi, lưu lời giải vào bảng phương án
- Xét bài toán thứ i: F[i] (1<=i<=n+1)
-Xét bài toán thứ j: (0<=j<i)
Nếu (a[j] < a[i] và F[i] < F[j] + 1) thì:
{ F[i]= F[j] + 1 (công thức truy hồi)
Lưu lời giải vào mảng vet: vet[i]=j}
=> Độ dài của dãy con tăng dài nhất là F[n+1] -2
Bước 3 Truy vết, tìm nghiệm của bài toán dựa vào bảng phương án.
Ta duyệt từ cuối về đầu:
for (int i=1; i<=n; i++) cin>> a[i];
a[0]= -inf; a[n+1]=inf;
F[0]=1;
Trang 8for (int i=1; i<=n+1; i++)
for (int j=0; j<i; j++)
if (a[j] < a[i] && F[i] < F[j]+1)
vet[i]= j;
}cout<<F[n+1] - 2<<'\n';
for (int i=n+1; i>0; i=vet[i])
Bài toán 2: Dãy con có tổng bằng S.
chọn ra trong dãy một dãy con có tổng bằng S (không nhất thiết các phần tử phảiliên tiếp)
Input: - Dòng 1: chứa số nguyên dương n và S (1<=n<=100, 1<=S<=10000)
- Dòng 2: chứa n số nguyên dương a1, a2, a3, …, an (1<=ai <=100)Output: - Nếu có thể chọn ra được dãy con có tổng bằng S thì:
+ Dòng đầu ghi thông báo: "YES"
+ Dòng thứ 2 đưa ra dãy các vị trí của dãy con có tổng bằng S
- Ngược lại thì ghi thông báo "NO"
Các bước giải bài toán:
Bước 1: Phân rã bài toán cần giải thành những bài toán con giống hệt nó
nhưng có kích thước nhỏ hơn
bằng j
j (1<=i<=n; 0<=j<=S), ngược lại F[j]=0
Bước 2
Bước 2.1: Giải bài toán con nhỏ nhất:
Trang 9Lưu lời giải vào mảng vet:
nếu vet[j]= 0 thì vet[j] = i;
for (int i=1; i<=n; i++ )
for (int j= S; j>=a[i]; j )
if (F[j-a[i]] ==1)
if (vet[j]==0) vet[j]=i;
}
Trang 10if (F[S]==0) cout<<"NO";
else{ cout<<"YES \n";
for (int j=S; j>0; j=j-a[vet[j]]) kq.push_back(vet[j]]);
for (int i=kq.size()-1; i>=0; i ) cout<<kq[i]<<" ";
}return 0;
}
Bài toán 3: Xâu con chung dài nhất
Xâu con của xâu X thu được bằng cách xóa đi một vài ký tự của X và giữ nguyên vị trí của các ký tự còn lại Ví dụ: ‘abc’ là xâu con của xâu ‘adcberc’, và không phải là xâu con của xâu ‘adcber’
Cho hai xâu ký tự là X và Y (cả 2 xâu X và Y có số lượng ký tự không quá100)
Tìm xâu con chung có độ dài lớn nhất của hai xâu X và Y
- Dòng 2 xâu Y
- Dòng 2: các vị trí trong xâu X của xâu con chung dài nhất
- Dòng 3: các vị trí trong xâu Y của xâu con chung dài nhất
Các bước giải bài toán:
Bước 1: Phân rã bài toán cần giải thành những bài toán con giống hệt nó
nhưng có kích thước nhỏ hơn
Y = Y1Y2… Yj (Y1 ,Y2,…,Yn được gọi là các kí tự của xâu Y)
Khi đó độ dài của dãy con chung dài nhất của X và Y sẽ là F[m][n]
Bước 2
Bước 2.1: Giải bài toán con nhỏ nhất:
Trường hợp đơn giản nhất: độ dài của dãy con chung dài nhất của mộtdãy rỗng và một dãy kí tự bất kỳ luôn bằng 0 Do đó:
F[0][j] = F[i][0] = 0 với mọi i, j
Trang 11Bước 2.2: Tìm công thức truy hồi, lưu lời giải vào bảng phương án
Xét 2 kí tự Xi và Yj:
-Nếu Xi = Yj thì F[i][j]= F[i-1][j-1] +1
-Nếu Xi ≠ Yj thì F[i][j]= F[i-1][j] hoặc F[i][j]= F[i][j-1] Do đó:
F[i][j]= max( F[i-1][j] , F[i][j-1])
Bước 3 Truy vết, tìm nghiệm của bài toán dựa vào bảng phương án.
i=m; j=n
Lặp lại các thao tác sau đây khi i>0 và j>0:
i = i-1 và j = j-1Nếu Xi ≠ Yj thì:
-nếu F[i][j]= F[i-1][j] thì i = i-1-nếu F[i][j]= F[i][j-1] thì j=j-1}
CODE tham khảo:
else F[i][j]=max (F[i-1][j],F[i][j-1])for (int i=m, j=n; i>0 && j>0; )
if (X[i]==Y[j])
x[i]=y[j]=1;
Trang 12i ; j ;
}else
if (F[i][j] = F[i-1][j] ) i ;
Bài toán 4 Cái túi (phiên bản 01).
Trong truyện cổ tích "Cây Khế" ta đã biết rằng chim thần chở người em vớimột cái túi ba gang đến hòn đảo đầy vàng bạc châu báu Người em băn khoănkhông biết chọn đồ vật nào cho vào túi vì chỉ có một cái túi ba gang
Giả sử rằng trên hòn đảo kia có N đồ vật khác nhau, đồ vật thứ i có giá trị là
là M Bạn hãy giúp người em chọn ra trong N đồ vật trên một số đồ vật sao chotổng thể tích của các đồ vật được chọn không vượt quá M và tổng giá trị các đồ vậtđược chọn là lớn nhất
Input: - Dòng đầu tiên ghi hai số N, M (N,M≤100)
tích của đồ vật thứ i (ai, bi≤100)
Output: - Dòng đầu tiên ghi tổng giá trị lớn nhất có thể cho vào trong túi
- Dòng thứ hai ghi số hiệu các đồ vật được cho vào trong túi Đầu tiên ghi
K là số lượng đồ vật được chọn, tiếp theo là K số thể hiện số hiệu các đồvật được chọn
Trang 13Bước 1: Phân rã bài toán cần giải thành những bài toán con giống hệt nó
nhưng có kích thước nhỏ hơn
- Ta tìm cần tìm tổng giá trị lớn nhất được chọn từ đồ vật thứ 1 đến đồ vậtthứ i cho vào túi có thể tích là j (1<=i<=n; 1<=j<=m)
Khi đó, ta gọi: F[i][j] là tổng giá trị lớn nhất được chọn từ đồ vật thứ 1đến đồ vật thứ i cho vào túi có thể tích là j
Tổng giá trị lớn nhất lấy được là: F[n][m]
F[i][j] = F[i-1][j-b[i]] + a[i]
=>F[i][j] = max (F[i-1][j], F[i-1][j-b[i]] + a[i])Tóm lại ta có công thức truy hồi sau:
-Nếu j < b[i] thì F[i][j] = F[i-1][j]
-Nếu j>=b[i] thì: F[i][j] = max (F[i-1][j], F[i-1][j-b[i]] + a[i])
Bước 3 Truy vết, tìm nghiệm của bài toán dựa vào bảng phương án.
i=n, j=m, d=0; //d dùng để đếm số đồ vật được chọn
Lặp lại các thao tác sau trong khi i>0:
{ d++;
x[i]=1; //đánh dấu đồ vật thứ i được lấyi=i-1 ; j=j-b[i] ;
Trang 14}Ngược lại thì i=i-1}
Code tham khảo:
for (int i=1; i<=n; i++ ) cin>>a[i]>>b[i];
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++ )
if (j < b[i]) F[i][j] = F[i-1][j];
else F[i][j] = max(F[i-1][j], F[i-1][j-b[i]] + a[i]);
for (int i=1; i<=n; i++)
Trang 15Một va ly có thể chứa W đơn vị trọng lượng Có n đồ vật mỗi vật có trọnglượng A[i] và có giá trị C[i] hỏi lên chọn mỗi loại đồ vật bao nhiêu để xếp vào valysao cho tổng giá trị của valy là lớn nhất.
Dữ liệu vào: - Dòng đầu tiên là số N và W (1 ≤ N, W ≤ 100)
- Dòng thứ i trong số N dòng tiếp theo mỗi dòng ghi hai số A[i] vàC[i] (1 ≤ A[i], C[i] ≤ 100)
Kết quả ra :
- Dòng đầu tiên là tổng giá trị lớn nhất tìm được của valy
- Các dòng tiếp theo mỗi dòng ghi hai số i (là số hiệu vật được chọn) x (là sốlượng chọn vật i)
Các bước giải bài toán:
Bước 1: Phân rã bài toán cần giải thành những bài toán con giống hệt nó
nhưng có kích thước nhỏ hơn
Thực hiện tương tự như bài toán 2 và bài toán 4 ta được:
Gọi F[j] là tổng giá trị lớn nhất khi chọn các đồ vật cho vào túi có thể tích j.Tổng giá trị lớn nhất tìm được là: F[w]
Trang 16Bước 3 Truy vết, tìm nghiệm của bài toán dựa vào bảng phương án.
for (int i=1; i<=n; i++)
for (int j=a[i]; j<=w; j++ )
if (F[j] < F[j-a[i]] + c[i])
vet[j] = i;
}cout<<F[w]<<'\n';
return 0;
}
b) Một số bài tập tham khảo: