Tải bản đầy đủ (.doc) (37 trang)

ôn tập cấu trúc dữ liệu và giải thuật

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 (161.19 KB, 37 trang )

CÂU HỎI ÔN TẬP
Phần 1. CTDL và Thuật giải
1. Cho 1 mảng gồm n các số nguyên a[1], a[2],.., a[n] và một số nguyên S. Khai báo cấu trúc
dữ liệu và viết thuật giải tìm tất cả các dãy con {x1, x2,.., xk} sao cho:
1 <= k <= n;
1 <= x1 < x2 < .. < xk <= n ;
và a[x1] + a[x2] + ..+ a[xk] = S
2. Có N gói kẹo được đánh số từ 1 đến N (N<=100). Gói thứ i có A i cục kẹo. Khai báo cấu trúc
dữ liệu và viết thuật giải chia N gói kẹo thành hai phần sao cho độ chênh lệch số kẹo giữa
hai phần là ít nhất. Yêu cầu, không được thay đổi số kẹo trong mỗi gói. Cho biết độ chênh
lệch nhỏ nhất giữa hai phần và danh sách gói kẹo của từng phần.
3. Có N chi tiết, được đánh số từ 1 tới N, cần được gia công. Các chi tiết có thể cho gia công
trên máy A hoặc máy B. Các máy này có thể hoạt động độc lập hay đồng thời. Biết rằng thời
gian gia công chi tiết i trên máy A là a[i] và trên máy B là b[i] (1 ≤ i ≤ n).
Khai báo cấu trúc dữ liệu và viết thuật giải tìm 1 phương án phân công cho các máy để thời
gian hoàn thành cả N chi tiết là sớm nhất.
4. Có N đồ vật được đánh số từ 1 đến N. Đồ vật thứ i có trọng lượng là A i và có giá trị sử dụng
là Ci. Một người cần chọn một số đồ vật trong N đồ vật đó sao cho tổng giá trị các đồ vật
được chọn là lớn nhất nhưng tổng trọng lượng của chúng không vượt quá giá trị M cho
trước.
Khai báo cấu trúc dữ liệu và viết thuật giải xác định các đồ vật cần chọn.
5. Trong cửa hàng có N mặt hàng được đánh số từ 1 đến N, mặt hàng thứ i có giá tiền là A i.
Một người cha mang theo số tiền là M cần chọn 4 mặt hàng khác nhau để làm quà cho các
con, sao cho tổng số tiền của 4 mặt hàng này không lớn hơn số tiền M mang theo và độ
chênh lệch giá tiền của mặt hàng đắt nhất và mặt hàng rẻ nhất trong 4 mặt hàng được chọn là
nhỏ nhất.
Khai báo cấu trúc dữ liệu và viết thuật giải xác định 4 mặt hàng đó.
6. Có 2 đội cờ A và B, mỗi đội có N người được đánh số từ 1 đến N, tham gia thi đấu N trận,
mỗi trận đấu gồm một người của đội A và một người của đội B. Huấn luyện viên của đội A
tự đánh giá trình độ của người thứ i trong đội A là A i và trình độ của người thứ i trong đội B
là Bi. Hai người thi đấu có cùng trình độ thì hòa; người nào có trình độ cao hơn thì thắng.


Mỗi trận nếu thắng thì được 2 điểm, hòa 1 điểm, thua 0 điểm. Khai báo cấu trúc dữ liệu và
viết thuật giải sắp xếp lịch thi đấu để đội A được nhiều điểm nhất, cho biết danh sách các cặp
thi đấu.
7. Cho dãy A gồm N số nguyên. Khai báo cấu trúc dữ liệu và viết thuật giải để tìm các hoán vị
{X1, X2, .., Xn} của tập {1, 2, .., N} sao cho A[X1] <= A[X2] <=..<= A[XN].
Ví dụ:
i

1

2

3

4

5

A[i]

6

2

8

4

9



Hoán vị X cần tìm:
i

1

2

3

4

5

X[i]

2

4

1

3

5b

A[X[i]]

2


4

6

8

9

8. Cho N loại tờ giấy bạc (N < 50). Tờ giấy bạc thứ i có mệnh giá phân biệt là A[i]. Số tờ mỗi
loại không giới hạn. Cần chi trả cho khách hàng số tiền M đồng. Khai báo cấu trúc dữ liệu và
viết thuật giải cho biết mỗi loại tiền cần bao nhiêu tờ sao cho tổng số tờ là ít nhất.
Ví dụ: N = 4 và M = 10
Mảng A chứa các giá trị {1, 2, 3, 4}
Kết quả: Số tờ = 3
Trong đó : 2 to loai 4, 1 to loai 2
9. Có N phòng học, được đánh số từ 1 đến N, phòng học thứ i có sức chứa là P[i] sinh viên; và
K lớp học (K<=N), được đánh số từ 1 đến K, lớp học thứ j có số sinh viên là L[j]. Phòng đào
tạo cần xếp phòng cho các lớp, mỗi lớp 1 phòng.
Khai báo cấu trúc dữ liệu và viết thuật giải chọn ra K phòng để xếp cho các lớp, sao cho tổng
số chỗ trống của các phòng được chọn là nhỏ nhất. Cho biết các phòng đó là những phòng
nào, lớp được xếp tương ứng cho mỗi phòng.
10. Tại một kho chứa hàng có N khu vực, mỗi khu vực được đánh số từ 1 đến N, khu vực thứ i
có sức chứa là V[i] container. Người ta cần chất M container vào các khu vực này.
Khai báo cấu trúc dữ liệu và viết thuật giải chọn ra các khu vực được dùng để xếp M
container sao cho phần còn trống sau khi đã xếp M container ở các khu vực đó là ít nhất.
11. Trong một kho hóa chất hiện có N thùng chứa cùng một loại dung dịch. Thùng thứ i hiện
chứa A[i] lít dung dịch. Do các thùng chứa đã cũ, nên người ta cần bỏ một số thùng cũ và
chứa dung dịch sang những thùng chứa mới.
Khai báo cấu trúc dữ liệu và viết thuật giải xác định số thùng cũ nhiều nhất cần loại bỏ sao
cho dung dịch của các thùng đó được đổ đầy vào các thùng chứa mới. Biết rằng, số thùng

mới không hạn chế và mỗi thùng đều có dung tích là M lít.
Ví dụ: N = 6; M = 50

Kết quả : Số thùng cũ lớn nhất là: 4

A = {10, 30, 20, 60, 50, 70}
12. Một dãy N số (X1 X2…XN) là một hoán vị hoàn toàn của các số từ 1 đến N nếu nó là một
hoán vị và thỏa mãn điều kiện Xi ≠ i với ∀i : 1 ≤ i ≤ N.
Khai báo cấu trúc dữ liệu và viết thuật giải liệt kê tất cả các hoán vị hoàn toàn của các số từ 1
đến N.
13. Có N thành phố được mã hóa bằng các số từ 1 đến N, chi phí đi từ thành phố i đến thành phố
j là C[i,j] với 1≤ i, j ≤ n. Một người đang ở thành phố có mã số 1, muốn đi qua tất cả các
thành phố khác và kết thúc tại thành phố có mã số N.


Khai báo cấu trúc dữ liệu và viết thuật giải xác định danh sách các thành phố phải đi qua sao
cho tổng chi phí theo hành trình này là ít nhất và trên hành trình đó không được đi qua một
thành phố nào đó quá 1 lần.
14. Khai báo cấu trúc dữ liệu và viết thuật giải tìm tập hợp các dấu '+’, ‘-‘ và không dấu giữa
dãy số 123456789 sao cho được một biểu thức có giá trị bằng một số nguyên N cho trước.
Ví dụ: N = 280 ta có các tổ hợp sau:
1 + 2 + 345 – 67 + 8 – 9
1 + 234 – 5 + 67 – 8 – 9
123 – 4 + 5 + 67 + 89
15. Khai báo cấu trúc dữ liệu và viết thuật giải xác định tất cả các cách phân tích số tự nhiên N
>1 thành tổng các số tự nhiên nhỏ hơn nó (mọi phân tích chỉ kể đúng một lần: 4+3+1 và
1+4+3 chỉ là một)
16. Có n thành phố (được đánh số từ 1 đến n). Một người đi du lịch xuất phát từ thành phố số 1
muốn đi thăm các thành phố khác, mỗi thành phố đúng một lần rồi quay về nơi xuất phát.
Giả thiết biết được chi phí đi từ thành phố i đến thành phố j là C[i, j] với 1≤ i, j ≤ n.

Khai báo cấu trúc dữ liệu và viết thuật giải xác định một hành trình cho người du lịch để
tổng chi phí theo hành trình này là ít nhất.

2

1

3

3
1
1

2

4

2

4

17. Người ta cần đặt 8 Quân Hậu vào các ô trên bàn cờ quốc tế có kích thước 8 dòng và 8 cột
sao cho các quân Hậu không ăn nhau. Biết rằng 2 quân Hậu không ăn nhau nếu chúng không
cùng nằm trên một dòng hoặc trên một cột hoặc trên các đường chéo.
Hãy khai báo cấu trúc dữ liệu và viết thuật giải xác định các ô cần đặt 8 quân hậu trên bàn
cờ.


18. Trên bàn cờ quốc tế có kích thước 8 dòng và 8 cột, người ta đặt Quân Mã tại ô thuộc dòng 1
cột 1. Khai báo cấu trúc dữ liệu và viết thuật giải xác định các bước đi của Quân Mã trên tất

cả các ô của bàn cờ sao cho mỗi ô chỉ đi qua một lần.

19. Mỗi hột xí ngầu có 6 mặt, mỗi mặt chứa từ 1 đến 6 dấu chấm. Khai báo cấu trúc dữ liệu và
viết thuật giải liệt kê các kết quả phân biệt có thể có khi đổ cùng lúc 3 hột xí ngầu, không kể
thứ tự xuất hiện trên các hột xí ngầu, ví dụ {1, 2, 3} và {2, 3, 1} là như nhau.
20. Khai báo cấu trúc dữ liệu và viết thuật giải điền vào một ma trận vuông cấp 3 các số từ 1 đến
9 sao cho các số ở dòng thứ i hợp thành 1 số gấp i lần số hợp bởi dòng thứ 1.
Ví dụ :
2

7

3

5

4

6

8

1

9


HƯỚNG DẪN BÀI GIẢI
1. Cho 1 mảng gồm n các số nguyên a[1], a[2],.., a[n] và một số nguyên S. Khai báo cấu trúc dữ
liệu và viết thuật giải tìm tất cả các dãy con {x1, x2,.., xk} sao cho:

1<=x1Khai báo cấu trúc:
Input:
Mảng nguyên A[1..N];
Số nguyên S : Giá trị điều kiện cho trước;
Output:
Mảng nguyên X[1..N]: chứa dãy nhị phân với qui ước X[i] =1 thì A[X[i]] được chọn.

Thuật giải: Khởi tạo giá trị ban đầu
{
NhậpMảng(A);
Nhập(S);
Xác định giá trị phần tử X[1];
}

Thuật giải: Xác định giá trị phần tử X[i]
Input:
Mảng nguyên X cần xác định giá trị phần tử
Số nguyên i: chỉ số phần tử cần xác định
Output:
X[i]: chứa giá trị 0 hay 1;
{
for (int v =0; v<= 1; v++)


{
X[ i ] = v;
if ( i == n )
Kiểm_Tra_Mảng_X();
else

Xác định giá trị phần tử X[i + 1];
}
}

Thuật giải: Kiểm Tra Mảng X
{
int T = 0;
for(int j =1; j<= n; j++)
if (X[j] == 1) T = T + A[X[j]];
if (T==S)
for(int j =1; j<= n; j++)
if (X[j] == 1) Xuất( j );
}
2. Có N gói kẹo được đánh số từ 1 đến N (N<=100). Gói thứ i có A i cục kẹo. Khai báo cấu trúc
dữ liệu và viết thuật giải chia N gói kẹo thành hai phần sao cho độ chênh lệch số kẹo giữa
hai phần là ít nhất. Yêu cầu, không được thay đổi số kẹo trong mỗi gói. Cho biết độ chênh
lệch nhỏ nhất giữa hai phần và danh sách gói kẹo của từng phần.
Khai báo cấu trúc:
Input:
Mảng nguyên A[1..N]: số kẹo trong từng gói kẹo;
Output:
Mảng Y[1..N] : chứa dãy nhị phân xác định gói kẹo được chọn tối ưu.
Temp:


Mảng X[1..N]: chứa dãy nhị phân xác định gói kẹo được chọn.
D : độ lệch số kẹo nhỏ nhất giữa 2 phần;

Thuật giải: Khởi tạo giá trị ban đầu
{

NhậpMảng(A[1..N]);
Xác định giá trị phần tử X[1];
In nghiệm tối ưu dựa trên mảng Y;
}

Thuật giải: Xác định giá trị phần tử X[i]
{
for (int v =0; v<= 1; v++)
{
X[ i ] = v;
if ( i == N )
Kiểm_Tra_Mảng_X();
else
Xác định giá trị phần tử X[ i + 1];
}
}
Thuật giải: Kiểm Tra Mảng X
{
S1=S2 = 0
for(int j =1; j<=K; j++)
if (X[j] == 0)
S1 +=A[X[j]];
else


S2+=A[X[j]];
if (abs(S1-S2){
Y = X;
D= abs(S1-S2);

}
}

3. Có N chi tiết, được đánh số từ 1 tới N, cần được gia công. Các chi tiết có thể cho gia công
trên máy A hoặc máy B. Các máy này có thể hoạt động độc lập hay đồng thời. Biết rằng thời
gian gia công chi tiết i trên máy A là a[i] và trên máy B là b[i] (1 ≤ i ≤ n). Khai báo cấu trúc
dữ liệu và viết thuật giải tìm 1 phương án phân công cho các máy để thời gian hoàn thành
cả N chi tiết là sớm nhất.
Khai báo cấu trúc:
Input:
Mảng nguyên A[1..N];
Mảng nguyên B[1..N];
Output:
Mảng Y[1..N] : chứa dãy nhị phân xác định phương án được chọn tối ưu.
Temp
Mảng X[1..N]: chứa dãy nhị phân xác định chi tiết được gia công trên A hay B
D : thời gian của phương án tối ưu.

Thuật giải: Khởi tạo giá trị ban đầu
{
NhậpMảng(A[1..N]);
NhậpMảng(B[1..N]);
Xác định giá trị phần tử X[1];
In nghiệm tối ưu chứa trong mảng Y;


}

Thuật giải: Xác định giá trị phần tử X[i]
{

for (int v =0; v<= 1; v++)
{
X[ i ] = v;
if ( i == N )
Cập nhật lời giải tối ưu();
else
Xác định giá trị phần tử X[ i + 1];
}
}

Thuật giải: Cập nhật lời giải tối ưu
{
S = 0;
for(int j =1; j<=N; j++)
if (X[j] == 0)
S +=A[X[j]];
else
S+=B[X[j]];
if (S{
Y = X;
D= S;
}
}


4. Có N đồ vật được đánh số từ 1 đến N. Đồ vật thứ i có trọng lượng là A i và có giá trị sử dụng
là Ci. Một người cần chọn một số đồ vật trong N đồ vật đó sao cho tổng giá trị các đồ vật
được chọn là lớn nhất nhưng tổng trọng lượng của chúng không vượt quá M. Khai báo cấu
trúc dữ liệu và viết thuật giải xác định các đồ vật cần chọn.

Khai báo cấu trúc:
Input:
Mảng A[1..N] chứa trọng lượng của mỗi đồ vật;
Mảng C[1..N] chứa giá trị của mỗi đồ vật;
Output:
Mảng Y[1..N] : chứa dãy nhị phân xác định phương án được chọn tối ưu.
Temp
Mảng X[1..N]: chứa dãy nhị phân xác định vật được chọn
D : Tổng giá trị vật chọn theo phương án tối ưu;

Thuật giải: Khởi tạo giá trị ban đầu
{
NhậpMảng(A[1..N]);
NhậpMảng(C[1..N]);
Xác định giá trị phần tử X[1];
In nghiệm tối ưu chứa trong mảng Y;
}

Thuật giải: Xác định giá trị phần tử X[i]
{
for (int v =0; v<= 1; v++)
{
X[ i ] = v;


if ( i == N )
Cập nhật lời giải tối ưu();
else
Xác định giá trị phần tử X[ i + 1];
}

}
Thuật giải: Cập nhật lời giải tối ưu
{
S = W = 0;
for(int j =1; j<=N; j++)
if (X[j] == 1)
{
S +=C[X[j]];
W+=A[X[j]];
}
else
S+=B[X[j]];
if (W<=M && S>D)
{
Y = X;
D= S;
}
}

5. Trong cửa hàng có N mặt hàng được đánh số từ 1 đến N, mặt hàng thứ i có giá tiền là A i.
Một người cha mang theo số tiền là M cần chọn 4 mặt hàng khác nhau để làm quà cho các
con, sao cho tổng số tiền của 4 mặt hàng này không lớn hơn số tiền M mang theo và độ
chênh lệch giá tiền của mặt hàng đắt nhất và mặt hàng rẻ nhất trong 4 mặt hàng được chọn
là nhỏ nhất. Khai báo cấu trúc dữ liệu và viết thuật giải xác định 4 mặt hàng đó.


Khai báo cấu trúc:
Input:
Mảng A[1..N] chứa giá tiền của mỗi mặt hàng;
M : Số tiền mang theo;

Output:
Mảng Y[1..4] : chứa phương án được chọn tối ưu.
Temp
Mảng X[0..4]: chứa dãy chỉ số của 4 mặt hàng được chọn
D : Độ chênh lệch theo phương án tối ưu;

Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng A[1..N];
Nhập số tiền (M);
X[0] = 0
Xác định giá trị phần tử X[1];
In nghiệm tối ưu chứa trong mảng Y;
}

Thuật giải: Xác định giá trị phần tử X[i]
{
for (int v =X[i-1]+1; v<= N-K-i; v++)
{
X[ i ] = v;
if ( i == 4 )
Cập nhật lời giải tối ưu();
else
Xác định giá trị phần tử X[ i + 1];


}
}
Thuật giải: Cập nhật lời giải tối ưu
{

m = M = A[X[1]];
for(int j =2; j<=4; j++)
if (A[X[j]] m = A[X[j]];
else
if (A[X[j]] >M) M = A[X[j]];
if (M-m{
Y = X;
D= M-m;
}
}

6. Có 2 đội cờ A và B, mỗi đội có N người được đánh số từ 1 đến N, tham gia thi đấu N trận,
mỗi trận đấu gồm một người của đội A và một người của đội B. Huấn luyện viên của đội A
tự đánh giá trình độ của người thứ i trong đội A là A i và trình độ của người thứ i trong đội B
là Bi. Hai người thi đấu có cùng trình độ thì hòa; người nào có trình độ cao hơn thì thắng.
Mỗi trận nếu thắng thì được 2 điểm, hòa 1 điểm, thua 0 điểm. Khai báo cấu trúc dữ liệu và
viết thuật giải sắp xếp lịch thi đấu để đội A được nhiều điểm nhất.
Khai báo cấu trúc:
Input:
Mảng A[1..N] chứa trình độ mỗi vận động viên đội A;
Mảng B[1..N] chứa trình độ mỗi vận động viên đội B;
Output:
Mảng Y[1..4] : chứa phương án được chọn tối ưu.


Temp
a. Mảng X[1..N]: chứa hoán vị tìm được
b. Mảng F[1..N] : ghi nhớ tình trạng đã chọn của từng giá trị trong tập S={1, 2, .., n}, với

qui ước:
F[ v ] = 0 nếu v chưa chọn
F[ v ] = 1 nếu v đã chọn
− D : Chứa điểm của phương án tối ưu;
Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng A[1..N];
Nhập Mảng B[1..N];
F[1..N] = 0;
Xác định giá trị phần tử X[1];
In nghiệm tối ưu chứa trong mảng Y;
}

Thuật giải: Xác định giá trị phần tử X[i]
{
for (int v =1; v<= N; v++)
if (F[v]==0)
{

X[ i ] = v;
if ( i == N )
Cập nhật lời giải tối ưu();
else
{

F[v]= 1;
Xác định giá trị phần tử X[ i + 1];
F[v]= 0;

}



}
}
Thuật giải: Cập nhật lời giải tối ưu
{
S = 0;
for(int j =1; j<=N; j++)
if (A[X[j]] > B[X[j]])
S+= 2;
else
if (A[X[j]] == B[X[j]]) S+= 1;
if (S>D)
{
Y = X;
D = S;
}
}

7. Cho dãy A gồm N số. Viết thuật toán tìm hoán vị {X1, X2, .., Xn} của tập {1, 2, .., n} sao cho
A[X1] <= A[X2] <=..<= A[Xn].
Khai báo cấu trúc:
Input:
Mảng A[1..N] chứa các số nguyên;
Output:
Mảng X[1..N]: chứa hoán vị tìm được
Temp
Mảng F[1..N] : ghi nhớ tình trạng đã chọn của từng giá trị trong tập S={1, 2, .., n}, với qui
ước:
F[ v ] = 0 nếu v chưa chọn



F[ v ] = 1 nếu v đã chọn

Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng A[1..N];
Khởi tạo mảng F[1..N] = 0;
Xác định giá trị phần tử X[1];
}

Thuật giải: Xác định giá trị phần tử X[i]
{
for (int v =1; v<= N; v++)
if (F[v]==0)
{

X[ i ] = v;
if ( i == N )
Kiểm Tra Mảng X ();
else
{

F[v]= 1;
Xác định giá trị phần tử X[ i + 1];
F[v]= 0;

}
}
}


Thuật giải: Kiểm Tra Mảng X
{
for(int j =1; j<=N-1; j++)
if (A[X[j]] > A[X[j+1]])


break;
if (j ==N) InHoanVi(X);
}

8. Cho N loại tờ giấy bạc (N < 50). Tờ giấy bạc thứ i có mệnh giá phân biệt là A[i]. Số tờ mỗi loại
không giới hạn. Cần chi trả cho khách hàng số tiền M đồng. Khai báo cấu trúc dữ liệu và viết
thuật giải cho biết mỗi loại tiền cần bao nhiêu tờ sao cho tổng số tờ là ít nhất. Nếu không
đổi được, thì thông báo “KHONG DOI DUOC”.
Khai báo cấu trúc:
Input:
a. Mảng A[1..N]: chứa mệnh giá loại giấy bạc
b. M: Số tiền cần chi trả.
Output:
− Mảng Y[1..N] : chứa phương án được chọn tối ưu.
Temp
c. Mảng X[1..N]: chứa số tờ từng loại tìm được
d. D : Tổng số tờ tối ưu
Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng A[1..N];
Nhập số tiền(M);
Tìm số tờ mệnh giá A[1] đổi số tiền M;
In nghiệm tối ưu chứa trong mảng Y;

}

Thuật giải: Tìm số tờ mệnh giá A[i] đổi số tiền M
{
for (int j = M/A[i]; j >= 1; j--)
{
X[i] = j;


if (M – A[i]*j == 0)
Cập nhật lời giải tối ưu();
else
{
Tìm số tờ mệnh giá A[i+1] đổi số tiền (M – A[i]*j);
X[i]=0;
}
}
}
Thuật giải: Cập nhật lời giải tối ưu
{
S = 0;
for(int v =1; v<=N-1; v++)
S+=X[v];
if (S < D)
{
Y = X;
D = S;
}
}


9. Có N phòng học, được đánh số từ 1 đến N, phòng học thứ i có sức chứa là P[i] sinh viên; và
K lớp học (K<=N), được đánh số từ 1 đến K, lớp học thứ j có số sinh viên là L[j]. Phòng đào
tạo cần xếp phòng cho các lớp, mỗi lớp 1 phòng. Khai báo cấu trúc dữ liệu và viết thuật giải
chọn ra K phòng để xếp cho các lớp, sao cho tổng số chỗ trống của các phòng được chọn là
nhỏ nhất. Cho biết các phòng đó là những phòng nào, lớp được xếp tương ứng cho mỗi
phòng.
Khai báo cấu trúc:


Input:
a. Mảng P[1..N]: Chứa số chỗ mỗi phòng
b. Mảng L[1..K]: Chứa sĩ số mỗi lớp
Output:


Mảng Y[1..K] : chứa phương án được chọn tối ưu.

Temp
c. Mảng X[1..K]: chứa chỉ số phòng được chọn.
d. Mảng F[1..N] : ghi nhớ tình trạng đã chọn của từng giá trị trong tập S={1, 2, .., n}, với
qui ước:
F[ v ] = 0 nếu v chưa chọn
F[ v ] = 1 nếu v đã chọn
e. D : Tổng chỗ trống tối ưu
Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng P[1..N];
Nhập mảng L[1..K];
Chọn phòng cho lớp thứ 1;
In nghiệm tối ưu chứa trong mảng Y;

}

Thuật giải: Chọn phòng cho lớp thứ (i)
{
for (int v =1; v<= N; v++)
if (F[v]==0 && P[v] >= L[i])
{

X[ i ] = v;
if ( i == K )
Cập nhật lời giải tối ưu;
else
{

F[v]= 1;


Chọn phòng cho lớp thứ ( i + 1 );
F[v]= 0;
}
}
}

Thuật giải: Cập nhật lời giải tối ưu
{
S = 0;
for(int j =1; j<=K; j++)
S += P[X[j]] - L[X[j]];
if (S{

Y = X;
D= S;
}
}

10. Tại một kho chứa hàng có N khu vực, mỗi khu vực được đánh số từ 1 đến N, khu vực thứ i
có sức chứa là V[i] container. Người ta cần chất M container vào các khu vực này. Khai báo
cấu trúc dữ liệu và viết thuật giải chọn ra các khu vực được dùng để xếp M container sao
cho phần còn trống sau khi đã xếp M container ở các khu vực đó là ít nhất.
Khai báo cấu trúc:
Input:
a. Mảng V[1..N]: sức chứa của từng khu vực
b. M : Số container
Output:
− Mảng Y[1..N] : chứa dãy nhị phân xác định phương án được chọn tối ưu.


Temp
c. Mảng X[1..N]: chứa dãy nhị phân xác định khu vực được chọn
d. D : Số chổ trống theo phương án tối ưu;
Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng V[1..N];
Nhập( M );
Chỉ định trạng thái chọn của khu vực 1;
In lời giải tối ưu dựa trên mảng Y;
}

Thuật giải: Chỉ định trạng thái khu vực (i)
{

for (int v =0; v<= 1; v++)
{
X[ i ] = v;
if ( i == N )
Cập nhật lời giải tối ưu;
else
Chỉ định trạng thái khu vực ( i + 1 );
}
}
Thuật giải: Cập nhật lời giải tối ưu
{
S = 0;
for(int j =1; j<=N; j++)
if (X[j] == 1)
S +=V[X[j]];


else
S+=B[X[j]];
if (S > M && S-M{
Y = X;
D= S-M;
}
}

11. Trong một kho hóa chất hiện có N thùng chứa cùng một loại dung dịch. Thùng thứ i hiện
chứa A[i] lít dung dịch. Do các thùng chứa đã cũ, nên người ta cần bỏ một số thùng cũ và
chứa dung dịch sang những thùng chứa mới. Hãy xác định số thùng cũ nhiều nhất cần loại
bỏ sao cho dung dịch của các thùng đó được đổ đầy vào các thùng chứa mới. Biết rằng, số

thùng mới không hạn chế và mỗi thùng đều có dung tích là M lít.
Khai báo cấu trúc:
Input:
a. Mảng A[1..N]: chứa dung tích các thùng.
b. M : Số lít
Output:
− Mảng Y[1..N] : chứa dãy nhị phân xác định phương án được chọn tối ưu.
Temp
c. Mảng X[1..N]: chứa dãy nhị phân xác định thùng cũ cần loại bỏ.
d. D : Số thùng cũ theo phương án tối ưu;
Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng A[1..N];
Nhập( M );
Chỉ định trạng thái loại bỏ của thùng thứ (1) ;
In lời giải tối ưu dựa trên mảng Y;
}


Thuật giải: Chỉ định trạng thái loại bỏ của thùng thứ (i)
{
for (int v =0; v<= 1; v++)
{
X[ i ] = v;
if ( i == N )
Cập nhật lời giải tối ưu;
else
Chỉ định trạng thái loại bỏ của thùng thứ ( i + 1 );
}
}


Thuật giải: Cập nhật lời giải tối ưu
{
S = 0;
for(int j =1; j<=N; j++)
if (X[j] == 1)
S +=A[X[j]];
if (S % M == 0 && S/M>D)
{
Y = X;
D= S/M;
}
}

12. Một dãy N số (X1 X2…XN) là một hoán vị hoàn toàn của các số từ 1 đến N nếu nó là một hoán
vị và thỏa mãn điều kiện Xi ≠ i với ∀i : 1 ≤ i ≤ N. Khai báo cấu trúc dữ liệu và viết thuật giải
liệt kê tất cả các hoán vị hoàn toàn của các số từ 1 đến N.


Khai báo cấu trúc:
Input:
a. Số nguyên N;
Output:
b. Mảng X[1..K]: chứa hoán vị tìm được
Temp
c. Mảng F[1..N] : ghi nhớ tình trạng đã chọn của từng giá trị trong tập S={1, 2, .., n}, với
qui ước:
F[ v ] = 0 nếu v chưa chọn
F[ v ] = 1 nếu v đã chọn


Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập( N );
Khởi tạo mảng F[1..N] = 0;
Xác định giá trị phần tử X[1];
}

Thuật giải: Xác định giá trị phần tử X[i]
{
for (int v =1; v<= N; v++)
if (F[v]==0 && i != v)
{
X[ i ] = v;
if ( i == N )
{
for(int j =1; j<=N; j++) Xuất (X[j]);
}


else
{
F[v]= 1;
Xác định giá trị phần tử X[i + 1];
F[v]= 0;
}
}
}

13. Có N thành phố được mã hóa bằng các số từ 1 đến N, chi phí đi từ thành phố i đến thành
phố j là C[i, j] với 1≤ i, j ≤ n. Một người đang ở thành phố có mã số 1, muốn đi qua các

thành phố khác và kết thúc tại thành phố có mã số N. Khai báo cấu trúc dữ liệu và viết thuật
giải xác định danh sách các thành phố phải đi qua sao cho tổng chi phí theo hành trình này
là ít nhất và trên hành trình đó không được đi qua một thành phố nào đó quá 1 lần.
Khai báo cấu trúc:
Input:
a. Mảng C[1..N,1..N]: chứa chi phí.
Output:
b. Mảng Y[1..N] : chứa hành trình được chọn tối ưu.
c. D : Chi phí theo phương án tối ưu;
Temp
d. Mảng X[1..N]: chứa hành trình tìm được
e. S : Chi phí hành trình tìm được.
f. Mảng F[1..N] : ghi nhớ tình trạng đã chọn của từng giá trị trong tập S={1, 2, .., n}, với
qui ước:
F[ v ] = 0 nếu v chưa chọn
F[ v ] = 1 nếu v đã chọn

Thuật giải: Khởi tạo giá trị ban đầu
{
Nhập Mảng C[1..N, 1..N];


×