Tải bản đầy đủ (.docx) (26 trang)

(SKKN 2022) 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, tỉnh thanh hóa

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (155.45 KB, 26 trang )

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ƯỜNG THPT LÊ LỢI, HUYỆN THỌ XUÂN,
TỈNH THANH HÓA

Người thực hiện: Lê Thị Huyên
Chức vụ: Giáo viên
SKKN thuộc lĩnh vực (môn): Tin học


THANH 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


1.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ủa
mỗi giáo viên nhằm nâng cao trình độ chun mơn nghiệp vụ, tích lũy kinh nghiệm
cho 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ỏi
mơn Tin học nói chung thì học sinh phải có vốn kiến thức về thuật tốn để giải
được các bài tố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 tốn đã tìm được và giải bài tốn theo yêu cầu. Chương
trì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ền tả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ôi
nhận thấy việc nắm vững các thuật tốn và áp dụng nó một cách linh hoạt trong các
bài tập nhất định là khơng đơn giản. Để có thể nhận dạng một bài tốn có thể thực
hiện với các thuật tốn khơng phải dễ. Ngồi ra để cài đặt được thuật tố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ật

tốn. Đa số học sinh cảm thấy khó khăn khi giải các bài tốn tin có liên quan đến
thuật tốn nâng cao, rất lúng túng trong q trình phân tích, tổ chức dữ liệu, tìm ra
thuật tốn hiệu quả. Vì vậy, để giúp học sinh tháo gỡ được những khó khăn, vướng
mắc trong q trình học tập, ơn luyện thi học sinh giỏi, thì bản thân tơi khơng
ngừ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úp
cho 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ản
thân nắm vững hơn nữa về tư duy thuật tố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 tố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ều
phươ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
tác bồi dưỡng học sinh giỏi với đề tài: "Sử dụng phương pháp quy hoạch động
3


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, tỉnh Thanh Hóa".
Trong q 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 hồ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 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 qt 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ường
THPT.
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 thực nghiệm.
2. NỘI DUNG

2.1 Cơ sở lí luận
Phương pháp quy hoạch động (Dynamic Programming) do nhà toán học
người Mỹ Richard Bellman (1920-1984) phát minh năm 1953. Phương pháp này
dùng để giải các bài tốn tối ưu có bản chất đệ quy, tức là tìm phương án tối ưu cho
bài tốn đó có thể đưa về tìm phương án tối ưu cho một số hữu hạn các bài toán
con.
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
tốn các cơng thức truy hồi bằng cách lưu tồn bộ hay một phần kết quả tính tốn
tại mỗi bước trước đó với mục đích sử dụng lại.

4


Đ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 tố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 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ịn

phương pháp quy hoạch động sử dụng ngun lý bottom-up, nghĩa là "đi từ dưới
lê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 ra
nghiệm. Sau đó, kết hợp các bài tố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.
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ơn
nữa, đó là môn không thi tốt nghiệp và đại học nên chưa được học sinh, phụ huynh
quan 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ều
khó 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 ưu
cá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ích
bài tốn, tổ chức dữ liệu, tìm ra thuật tốn hiệu quả để lập trình giải các bài tố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 khi
bài toán tối ưu đó có các đặc điểm sau đây:
- Bài tố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 tốn con đó cho ta lời giải của bài tố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.
- Q trình từ bài bài tốn cơ sở tìm ra lời giải bài toán ban đầu phải qua
hữ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 tốn con giống hệt nó
nhưng có kích thước nhỏ hơn.

5


Bước 2:
Bước 2.1: Giải bài toán con nhỏ nhất: Là bài tốn có thể giải được
trực tiếp (có thể có một bài tốn con nhỏ nhất cũng có thể có hai, ba
bà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 tố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ào
bảng phương án.
Bước 3: Truy vết, tìm nghiệm của bài tố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 tố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: a 1, 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ử
là a0 = -∞ và an+1 = +∞. Như vậy, dãy con tăng dài nhất sẽ bắt đầu từ phần tử a0 và
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 tố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
dãy con tăng dài nhất từ a0
dãy con tăng dài nhất từ a0

dãy con tăng dài nhất từ a0

đến a0.
đến a1.
đến a2.
đến an+1

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)
6


Gọ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:
Ta thấy F[0]=1 (độ dài của dãy con tăng dài nhất từ a0 đến a0 có độ dài
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<=jNế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 tốn dựa vào bảng phương án.
Ta duyệt từ cuối về đầu:
i=n+1.
Lặp lại trong khi i>0:
{

kq=kq + { a[i] }
i= vet[i]

}
Code tham khảo trên ngơn ngữ lập trình C++:
#include

<bits/stdc++.h>

#define

N

1000

#define

inf

int (1e9)

using namespace std;
int


n, k, ans, a[N+3], F[N+3], vet[N+3];

vector

<int> kq;

int

main()

{

cin>>n;
for (int i=1; i<=n; i++) cin>> a[i];
a[0]= -inf; a[n+1]=inf;
F[0]=1;
7


for (int i=1; i<=n+1; i++)
for (int j=0; jif (a[j] < a[i] && F[i] < F[j]+1)
{

F[i]= F[j]+1;
vet[i]= j;

}
cout<

for (int i=n+1; i>0; i=vet[i])
kq.push_back(a[i]);
for (int i=kq.size()-1; i>0; i--)
cout<return 0;
}
Bài tốn 2: Dãy con có tổng bằng S.
Cho dãy A gồm n số nguyên dương: a1, a2, a3,…, an và một giá trị S. Hãy
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ải
liê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.
Ta cần kiểm tra sự tồn tại của dãy con thuộc dãy từ a0 đến ai có tổng
bằng j.
Gọi F[j]=1 nếu tồn tại dãy con thuộc dãy từ a 0 đến ai có tổng bằng
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:
8


Ta thấy: F[0] = 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 a[i]: (1<=i<=n)
Xét j: (j=S chạy về a[i])
nếu F[j-a[i]] = 1 thì :
{

F[j] = 1
Lưu lời giải vào mảng vet:
nếu vet[j]= 0 thì vet[j] = 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.
Duyệt j=S về 1:
{

kq= kq + { vet[j]}
j = j - a[vet[j]];

}
Code tham khảo:
#include

<bits/stdc++.h>

#define

N

1000

#define


inf

int (1e9)

using namespace std;
int
vector

n, s, a[N+3], F[N+3], vet[N+3];
<int> kq;

int

main()

{

cin>>n>>S;
for (int i=1; i<=n; i++)

cin>>a[i];

F[0]= 0;
for (int i=1; i<=n; i++ )
for (int j= S; j>=a[i]; j--)
if (F[j-a[i]] ==1)
{

F[j]=1;

if (vet[j]==0) vet[j]=i;

}
9


if

(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<
}
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 q

100)
Tìm xâu con chung có độ dài lớn nhất của hai xâu X và Y.
Input:

- Dòng 1 xâu X
- Dòng 2 xâu Y

Output:

- Dòng 1: xâu con chung dài nhất của hai xâu X, 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 tốn con giống hệt nó
nhưng có kích thước nhỏ hơn.
Ta kí hiệu:

X = X1X2 … Xm (X1, X2, …,Xm được gọi các kí tự của xâu X).
Y = Y1Y2… Yj (Y1 ,Y2,…,Yn được gọi là các kí tự của xâu Y).

Gọi F[i][j] là độ dài của dãy con chung dài nhất của Xi và Yj
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ột
dãy rỗng và một dãy kí tự bất kỳ ln bằng 0. Do đó:
F[0][j] = F[i][0] = 0 với mọi i, j.
10



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 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 tố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:
{

Nếu Xi = Yj thì: Bổ sung Xi vào xâu con chung dài nhất.
i = i-1 và j = j-1
Nế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:
#include

<bits/stdc++.h>

using namespace std;
string X,Y, kq="";
int F[102][102], x[102], y[102];
int


main()

{

cin>>X>>Y;
int m=X.size(), n= Y.size();
X=' ' + X;

Y= ' ' +Y;

for (int i=1; i<=m; i++)
for (int j=1; j<=n; j++)
if (X[i]==Y[j])
else

F[i][j] = F[i-1][j-1] + 1;

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])
{

kq=X[i] + kq;
x[i]=y[j]=1;
11


i--; j--;

}
else
if (F[i][j] = F[i-1][j] ) i--;
else j--;
cout<for (int i=1; i<=m; i++)

if ( x[i]==1) cout << i <<" "<<'\n';

for (int i=1; i<=n; i++)

if ( y[i]==1) cout << i <<" ";

return 0;
}
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ới
mộ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ăn
khô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à
ai và có thể tích là bi. Cũng giả sử rằng cái túi mà người em mang đi chỉ có thể tích
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 cho
tổ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)
- N dòng tiếp theo, dòng thứ i ghi hai số a i và bi lần lượt là giá trị và thể
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.
Ví dụ:
INPUT
5 10
20 3
19 1
30 7
24 3
15 6
Các bước giải bài toán:

OUTPUT
63
3 1 2 4

12


Bước 1: Phân rã bài toán cần giải thành những bài tố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ật
thứ 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]
Bước 2.
Bước 2.1: Giải bài toán con nhỏ nhất:
Ta dễ thấy: F[0][j]=0
F[i][0]=0
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 đồ vật thứ i: (1<=i<=n)
Xét cái túi có thể tích j: (1<=j<=m)
- TH1: j < b[i] , tức là túi có thể tích là j bé hơn thể tích của vật
thứ i nên vật thứ i khơng lấy được. Do đó:
F[i][j] = F[i-1][j]
- TH2: j >=b[i], lúc này có thể lấy được vật thứ i. Nhưng cần
phải xem xét có nên lấy nó hay khơng. Cụ thể:
- Nếu khơng lấy đồ vật thứ i thì:
F[i][j] = F[i-1][j]
-Nếu lấy đồ vật thứ i thì:
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 tố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:
{

Nếu F[i][j] = F[i-1][j-b[i]] + a[i] thì:
{

d++;
x[i]=1; //đánh dấu đồ vật thứ i được lấy
i=i-1 ; j=j-b[i] ;

}
13



Ngược lại thì i=i-1
}
Code tham khảo:
#include

<bits/stdc++.h>

#define

N

100

using namespace std;
int n, m;
int

a[N+3], b[N+3];

int F[N+3][N+3] ;
int

main()

{

cin>>n>>m;
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]);

cout<int d=0;
for (int i=n,j=m; i>0; i-- )
if (F[i][j] != F[i-1][j])
{

d++;
x[i] = 1;
j=j - b[i];

}
cout<for (int i=1; i<=n; i++)
if (x[i]==1) cout<return 0;
}
Bài toán 5. Cái túi (tổng quát)

14



Một va ly có thể chứa W đơn vị trọng lượng. Có n đồ vật mỗi vật có trọng
lượ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 valy
sao 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)
Ví dụ:
input
4
5
1
8
2

10
4
9
90
16

output
108
2 2
3 1

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 tố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]
Bước 2.
Bước 2.1: Giải bài toán con nhỏ nhất:
Dễ thấy: F[0] = 0
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 đồ vật thứ i: (1<=i<=n)
Xét cái túi có thể tích j ( a[i] <=j<=w)
nếu (F[j] < F[j-a[i]] + c[i]) thì:
{

F[j] = F[j-a[i]] + c[i];
Vet[j] = i;

}
15


Bước 3. Truy vết, tìm nghiệm của bài tốn dựa vào bảng phương án.
j=w;
Trong khi j>0 thì thực hiện:
+ Chọn đồ vật có chỉ số là vet[j]
+ j = j-a[vet[j]]
Code tham khảo:
#include

<bits/stdc++.h>


#define

N 100

using namespace
int

std;

a[N+3], c[N+3], F[N+3], vet[N+3],

x[N+3];

int n,w;
int main()
{

cin>>n>>w;
for (int i=1; i<=n; i++) cin>>a[i]>>c[i];
F[0] = 0;
for (int i=1; i<=n; i++)
for (int j=a[i]; j<=w; j++ )
if (F[j] < F[j-a[i]] + c[i])
{

F[j] = F[j-a[i]] + c[i];
vet[j] = i;

}

cout<int

jmin=1;

for (int j=2; j<=w; j++)
if (F[jmin] < F[j])

jmin=j;

for (int j=jmin; j>0; j=j-a[vet[j]])
x[vet[j]] ++;
for (int i=1; i<=n; i++ )
if (x[i] > 0 )
cout<return 0;
}
b). Một số bài tập tham khảo:
16


Bài 1. Với một xâu ký tự S cho trước, ta có thể thực hiện các phép biến đổi sau:
• D: Xoá một ký tự của xâu S. Ký hiệu D i trong đó i là vị trí cần xóa
• I: Chèn trước vị trí t của xâu S một ký tự c nào đó. Ký hiệu I t c. Qui định
thêm về vị trí chèn: nếu xâu S có độ dài k, vị trí chèn là 1, 2, 3, ..., k+1, chèn
ở vị trí k+1 có nghĩa là viết thêm vào cuối xâu S
• R: Thay ký tự thứ t của S bởi ký tự c nào đó. Ký hiệu R t c
Giả sử X và Y là hai xâu ký tự. Độ dài xâu X là n, độ dài xâu Y là m (0≤m,n≤100)
Hãy tìm một dãy gồm ít nhất các phép biến đổi biến xâu X thành xâu Y (số phép
biến đổi ít nhất này gọi là khoảng cách giữa hai xâu)

INPUT:

-Dòng thứ nhất là xâu X
-Dòng thứ hai là xâu Y

OUTPUT:- Dòng thứ nhất ghi số K, đó là khoảng cách giữa hai xâu

- K dịng tiếp theo mỗi dòng ghi ký hiệu một phép biến đổi theo trình tự
thực hiện để biến X thành Y
Ví dụ:

INPUT
ertrtyui
tyuhj

OUTPUT
6
D1
D1
D1
D1
I4h
R5j

Bài 2. Cho hai số nguyên dương M, N (0a2, ..., am (A) và b1, b2, ...., bn (B). Tìm một dãy dài nhất C nhận được từ A bằng
cách xoá đi một số số hạng và cũng nhận được từ B bằng cách xố đi một số số
hạng (nói chung khơng cùng chỉ số như đối với dãy A). Ta gọi C là dãy con chung
dài nhất của hai dãy A, B.
INPUT:


- Dòng đầu tiên chứa hai số M, N

OUTPUT:

- Dòng thứ hai chứa M số a1, a2, ...., am
- Dòng thứ ba chứa N số b1, b2, ..., bn.
- Dòng thứ nhất ghi K là số lượng số hạng của dãy C
- Dòng thứ hai ghi K số là các số hạng của dãy C
- Dòng thứ ba ghi K số là chỉ số trong dãy A của K số hạng của C
- Dòng thứ tư ghi K số là chỉ số trong dãy B của K số hạng của C

Ví dụ:
17


INPUT

OUTPUT

56

3

23514

235

4 2 3 6 5 10


123
235

Bài 3. Bản đồ thành phố là một bảng kích thước M x N, các cột được đánh chỉ số
từ trái sang phải, các dòng được đánh chỉ số từ trên xuống dưới. Hiện nay thành
phố đang bị ô nhiễm nặng, trên mỗi ô (i,j) (giao nhau bởi dịng i và cột j) có A[i,j]
đơn vị rác thải.
Thị trưởng thành phố quyết định sử dụng một con robot đi thu gom rác ở các ô.
Robot được lập trình chỉ đi theo hướng xuống dưới, tức là từ ơ (i,j) robot chỉ có thể
đi tới ơ (i+1,j-1), (i+1,j) hoặc (i+1,j+1). Chính vì vậy để robot có thể thu gom được
nhiều rác nhất thì người ta phải cho robot xuất phát từ dòng 1 và đi xuống dịng M.
Hãy xác định vị trí cột xuất phát tại dịng 1 và hành trình của robot sao cho robot
có thể thu gom được nhiều rác thải nhất.
INPUT: - Dòng đầu chứa hai số M và N (1 <= M, N <= 1000).

- M dòng tiếp theo mỗi dòng ghi N số nguyên A[i,j] (0 <= A[i,j] <= 105)
cách nhau bởi 1 dấu cách.
OUTPUT: - Dòng đầu là số lượng rác thải lớn nhất thu được

- Dòng thứ 2 ghi số k là cột mà robot sẽ xuất phát tại dòng 1.
- Dòng thứ i + 2 ghi số L là cột mà robot sẽ đi trên hành trình từ dịng
2 tới dịng M
Ví dụ
INPUT

OUTPUT

5 4
4 5 2 4
3 4 5 2

3 4 5 2
5 6 3 5
4 5 2 5
Bài 4. Tích của hai ma trận A kích thước
ma trận C kích thước (n, m)
x

26
2
3
3
2
2
(n, p), ma trận B kích thước (p, m) là


18


Ví dụ trên là tích của hai ma trận kích thước (3, 4) x (4, 2) = (3, 2)
Số phép nhân để thực hiện nhân giữa hai ma trận A(n,p) với B(p,m) được ma trận
C(n,m) là n * p * m.
Phép nhân ma trận có tính chất kết hợp: A*B*C = (A*B)*C = A*(B*C), thứ tự
thực hiện phép nhân được thực hiện trong ngoặc trước, ngoài ngoặc sau.
Cho n ma trận A1, A2, A3, …, An với kích thước lần lượt là (d 0, d1), (d1, d2), (d2, d3),
…, (dn-1,dn).
Hãy tìm cách đặt các dấu ngoặc giữa các ma trận để tổng số phép nhân có kết quả
là ít nhất.
INPUT: - Dòng 1 chứa số nguyên dương n (1 ≤ n ≤ 100)


- Dòng 2 chứa n + 1 số nguyên dương d 0, d1, d2, …, dn là kích thước của các
ma trận (1 ≤ di ≤ 10).
OUTPUT: - Một dòng duy nhất là số phép nhân thực hiện ít nhất.

Ví dụ:
Input

Output

4
72
34234
Bài 5. Bờm chơi trò chơi điện tử Lucky Luke đến màn phải điều khiển Lucky leo
lên một cầu thang gồm N bậc (N<=1000).
Các bậc thang được đánh số từ 1 đến N từ dưới lên trên. Lucky có thể đi lên một
bậc thang, hoặc nhảy một bước lên hai bậc thang. Tuy nhiên một số bậc thang đã bị
thủng do cũ kỹ và Lucky không thể bước chân lên được. Biết ban đầu, Lucky đứng
ở bậc thang số 0 (tức là nền đặt thang).
Chơi đến đây, Bờm chợt nảy ra câu hỏi: có bao nhiêu cách để Lucky leo hết được
cầu thang? (nghĩa là leo đến bậc thang thứ N). Bạn hãy giúp Bờm trả lời câu hỏi.
Giả thiết rằng Bờm đã biết danh sách các bậc thang bị hỏng.
INTPUT:: Đọc từ file STEP.INP

o Dòng đầu chứa số N và k là số bậc thang và số lượng bậc thang bị hỏng
o Dòng thứ 2 ghi k số là danh sách của các bậc thang bị thủng.
OUTPUT:: Ghi ra file STEP.OUT 1 số duy nhất là số dư phép chia của kết quả tìm

được cho số 13051984
Ví dụ:
INPUT


41

OUTPUT

2

3
19


Bài 6. Một máy rút tiền tự động có n loại tiền mệnh giá lần lượt là d1, d2, …, dn
đồng. Bạn An cần rút số tiền là S sao cho tổng số tờ tiền rút được là ít nhất có thể.
Em hãy lập trình cho máy ATM có thể đưa ra tổng số lượng tờ tiền thỏa mãn yêu
cầu trên. Giả thiết rằng ln có cách rút tiền tối ưu.
INPUT:

- Dòng 1: chứa hai 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 d1, d2, …, dn (1 <= di <= 10000)
OUTPUT:

- Dòng 1: chứa số nguyên K là tổng số tờ tiền ít nhất.
- Dòng 2: chứa n số nguyên k1, k2, …, kn là số lượng tờ tiền tương ứng với các
mệnh giá d1, d2, …, dn.
Ví dụ:
INPUT

OUTPUT

3 35

124

10
118

2.4. Hiệu quả của sáng kiến kinh nghiệm.

Qua q trình triển khai đề tài tơi nhận thấy đã thu được kết quả thực sự. Đó là:
- Đa số học sinh đã nắm được các kiến thức, kỹ năng của bài học.
- Các em đã tự giải được một số bài toán tối ưu bằng phương pháp quy
hoạch động.
- Ban đầu động viên các em vào đội tuyển Tin học thật sự rất khó khăn.
Những ngày đầu học đội tuyển các em học một cách hời hợt, đối phó. Nhưng chỉ
sau một thời gian ngắn các em đã thực sự u thích, đam mê mơn Tin học. Qua đó
giúp các em có được định hướng nghề nghiệp sau này.
- Khi dạy đến chuyên đề giải các bài tốn tối ưu bằng phương pháp quy
hoạch động tơi đã chia đội tuyển thành 2 nhóm. Nhóm 1: tơi dạy theo phương pháp
thơng thường. Nhóm 2: tơi hướng dẫn học sinh sử dụng phương pháp quy hoạch
động như đã trình bày. Cuối chun đề tơi đã cho 2 nhóm cùng làm một bài kiểm
tra như nhau. Kết quả thu được rất khả quan. Cụ thể như sau:
Năm học
2020-2021
2021-2022

Nhóm
1
2
1
2


Điểm trung bình
13.0/20
17.5/20
13.5/20
18.0/20
20


3. KẾT LUẬN, KIẾN NGHỊ.

3.1. Kết luận.
Qua quá trình triển khai đề tài tôi rút ra được một số kinh nghiệm sau:
- Mỗi giáo viên cần phải nhận thức rằng khơng có một phương pháp tối ưu
nào dành cho tất cả các tiết dạy. Vì vậy trong quá trình dạy học, cần linh hoạt
trong việc sử dụng, kết hợp các phương pháp dạy học để giúp học sinh tiếp cận
nhanh nhất với nội dung bài học.
- Từ thực tế giảng dạy và bồi dưỡng học sinh giỏi, tôi nhận thấy: bài toán Tin
học đa dạng và phong phú. Người lập trình phải rất linh hoạt trong giải và cài đặt
chương trình. Đặc biệt với những bài tốn địi hỏi xử lý với dữ liệu lớn trong thời
gian hạn chế. Với mỗi dạng tốn cần có phương pháp giải phù hợp, với mỗi bài
tốn cần tìm giải thuật tốt (tối ưu) cùng với việc xây dựng cấu trúc dữ liệu lưu trữ
hợp lý. Qua các năm giảng dạy, cùng với sự tìm tịi các tài liệu, sách tham khảo và
mạng Internet cùng với cấu trúc đề ra và kiến thức cơ bản qua các kì thi chọn học
sinh giỏi Tỉnh, tơi thấy với giải pháp đã nêu có thể giúp học sinh có thêm kinh
nghiệm để giải nhiều bài tốn tương tự. Với mỗi giải pháp chúng ta có thể đưa ra
rất nhiều ví dụ để học sinh có thể vận dụng, tuy nhiên trong phạm vi của một sáng
kiến kinh nghiệm, tơi chỉ đưa ra một số ví dụ để trình bày. Vì kinh nghiệm chưa
nhiều, khơng thể tránh khỏi các hạn chế, rất mong muốn nhận được những góp ý từ
các bạn đồng nghiệp, hội đồng khoa học các cấp và bạn bè chia sẻ, bổ sung để đề
tài ngày càng hồn thiện hơn.

3.2. Kiến nghị


Nhà trường có kế hoạch bảo trì, nâng cấp phịng thực hành tin học tốt hơn để giúp
học sinh có điều kiện được thực hành. Trong phịng máy nên có máy chiếu để giáo
viên hướng dẫn học sinh thực hành được thuận tiện hơn.
• Tăng cường cho các giáo viên giảng dạy môn Tin học được tiếp thu các chuyên đề,
các phần mềm mới phục vụ cho công việc giảng dạy.
XÁC NHẬN CỦA HIỆU TRƯỞNG ĐƠN VỊ

Tôi xin cam đoan đây là SKKN của mình
viết, khơng sao chép nội dung của người khác.
Thanh Hóa, ngày 10 tháng 5 năm 2022
Người viết SKKN
21


Lê Thị Huyên

22


TÀI LIỆU THAM KHẢO
1. Hồ Sĩ Đàm (chủ biên) và nhóm tác giả - Sách giáo khoa Tin học 11 – Nhà
xuất bản giáo dục.
2. Hồ Sĩ Đàm (chủ biên) và nhóm tác giả - Sách bài tập Tin học 11 – Nhà xuất
bản giáo dục năm.
3. Hồ Sĩ Đàm (chủ biên) và nhóm tác giả - Sách giáo viên Tin học 11 – Nhà
xuất bản giáo dục năm.
4. Tài liệu giáo khoa chuyên tin, NXB Giáo dục, quyển 1, quyển 2, quyển 3,

Hồ Sĩ Đàm, Lê Minh Hoàng.
5. Tài liệu tập huấn giáo viên 2015, 2017 của Sở giáo dục và đào tạo Thanh
Hóa.
6. Sáng kiến kinh nghiệm của tác giả đã viết trong những năm học trước.
7. Phương pháp giải các bài toán Tin học – Trần Đức Huyên
8. Bài giảng chuyên đề - Lê Minh Hoàng (ebook).

23


DANH MỤC
SÁNG KIẾN KINH NGHIỆM ĐÃ ĐƯỢC HỘI ĐỒNG SÁNG KIẾN
KINH NGHIỆM NGÀNH GIÁO DỤC VÀ ĐÀO TẠO CẤP SỞ XẾP
LOẠI TỪ C TRỞ LÊN
Họ và tên tác giả: Lê Thị Huyên
Chức vụ và đơn vị công tác: Trường THPT Lê Lợi, Thọ Xuân, Thanh Hóa.
TT

1

2

3

4

5

6.


Tên đề tài SKKN
Nêu ứng dụng của bài toán
vào thực tế, phát triển bài
toán mới từ bài tốn đã có
qua tiết 15 (Tin Học 10): Câu
hỏi và bài tập về “Bài toán và
thuật toán"
Sử dụng phương pháp gợi
động cơ để dạy một số nội
dung trong chương VI:
“Chương trình con và lập
trình có cấu trúc”
Hướng dẫn học sinh phát hiện
và sửa lỗi cú pháp khi viết
chương trình bằng ngơn ngữ
lập trình Pascal trong chương
trình tin học lớp 11.
Một số phương pháp hữu
hiệu nhằm nâng cao chất
lượng dạy học môn Tin học
lớp 10 ở trường THPT Lê
Lợi, Thọ Xuân, Thanh Hóa.
Một số phương pháp hữu
hiệu nhằm nâng cao chất
lượng dạy học môn Tin học
lớp 11 ở trường THPT Lê
Lợi, Thọ Xuân, Thanh Hóa.
Một số biện pháp hữu hiệu
nhằm nâng cao chất lượng
dạy học bài “Cấu trúc lặp”

(Tin học 11) ở trường THPT
Lê Lợi, Thọ Xuân, Thanh
Hóa

Cấp đánh giá
xếp loại

Kết quả
đánh giá
xếp loại

Năm học
đánh giá
xếp loại

(Ngành GD cấp
huyện/tỉnh; Tỉnh...)

(A, B, hoặc C)

Sở GD

C

2010

Sở GD

C


2012

Sở GD

C

2013

Sở GD

C

2015

Sở GD

C

2016

Sở GD

C

2020

24


7


Sử dụng thuật toán đếm phân
phối để giải một số bài toán
tin học ở trường THPT Lê
Lợi, Thọ Xuân, Thanh Hóa.

Sở GD

C

2021

25


×