Thuật toán chia kẹo và ứng dụng giải lớp bài toán chia nhóm

9.3K 1 1
                                    

Thuật toán chia kẹo và ứng dụng giải lớp bài toán chia nhóm

Lã Thành Công

Xét một bài toán chianhóm tổng quát như sau:

Chon số a1, a2,...,an (n 'NI*) và m số b1, b2,..., bm (m < n,m ' NI*).

Yêucầu: Hãy chia n số a1, a2,..., an thành m nhómsao chotổng các phần tử của nhóm i bằng bi (i = 1,m).

Trướckhi đưa ra phương pháp giải bài toán trên ta xét bài toán đơn giản nhưng thú vịđó là bài "chia kẹo":

Có n gói kẹo mỗi góicóai cái kẹo (i= 1,n). Hãytìm cách chia n gói kẹo thành 2 nhóm sao cho chênh lệch giữa 2 nhóm là ít nhất.

Bài toán có thể giảitheo thuật toán sau:

Tađi xây dựng các tổng có thể có được từ gói kẹo. Ta thấy nếu tổng nào gồm (n div2) nhất thì đó là giá trị của nhóm 1. Phần còn lại sẽ thuộc vào nhóm 2. Để xâydựng được ta làm như sau:

Tadùng 3 mảng làm các công việc sau:

Mảng A dùng để ghi lại các giá trị của tổng

Mảng B dùng để ghi lại các phần tử cuối cùng cho vàođể đạt giá trị ở A.

Mảng C dùng để ghi lại các vị trí của tổng mà khôngcó phần tử ở B. Mảng này dùng để lần lại các phần tử có để đạt giá trị ở A.

Thựchiện như sau:

A[0]:=0; Max := 0; B [0]:= 0; C [0]:= 0;

Fori:= 1 to n do

For j:= 0 to max do

Begin

D:= True; m:= max;

For k:= 0 to max do if (A[j] +ai)= A[k] then D:= false;

If D then

Begin

inc (m);

A[m] := A[j] + ai;

B[m] := i;

C[m] := j;

end;

Thuậtgiải trên đã xây dựng được các tổng có thể có từ n gói kẹo. Khi chọn được A[i]gần với ( n div 2) nhất thì ta thực hiện thủ tục lần ngược như sau:

Fillchar(Logic, size of (logic), false);

WhileA[i] > 0 do

Begin

Logic [B[i]] := true; (cho phần tửB[i] vào nghiệm)

i:= c[i];

End;

Khiđó các phần tửmang giá trị Logic làtrue sẽ tạo thành một nhóm có tổng A[i] ban đầu.

Xéttiếp một bài toán ở mức độ cao hơn như sau:

Cho n số a1, a2,..., an(n ' NI*).

Tìmcách chia số trên thành m nhóm sao chomỗi nhóm đều có tổng bằng nhau và m tìm được là lớn nhất.

Cách giải : Bài toán trên ta có thể duyệtmọi m là ước số của T = Σ ai. Mà ở đó m chạytừ T về 1.

Vớimỗi m có được ta có tổng các nhóm sẽ là D =T/m. Với mỗi dự tuyển (m,D):

Một số bài toán QHĐNơi câu chuyện tồn tại. Hãy khám phá bây giờ