1. Trang chủ
  2. » Công Nghệ Thông Tin

Thuật toán quan hệ động mảng một chiều

7 936 10
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 7
Dung lượng 46 KB

Nội dung

Thuật toán quan hệ động mảng một chiều

Trang 1

Thuật toán quy hoạch động trên mảng một chiều

Trần Minh Quang

Bài toán 1: Cho một dãysố nguyên dương a1, a2, aN Hãy tỉa bớt mộtsố ít nhất các phần

tử của dãy số nguyên đó và giữ nguyên thứ tự các phần tửcòn lại sao cho dãy số còn lại là một dãy tăng dần Ta gọi dãy số nguyên tăngdần còn lại sau khi đã tỉa bớt một số phần tử

là dãy con của dãy đã cho

Input: Dữ liệu vào được cho bởi tệp văn bản với quy cách:

- Dòng đầu ghi số N là sốphần tử

- Dòng tiếp theo ghi N sốlà các số nguyên của dãy

Output:

-Ghi ra màn hình: Số lượng phần tử của dãy con cực đại và chỉ số các phần tửtrong dãy con đó (theo thứ tự tăng dần)

Ví dụ:

- Với Input trong fileDAYSO.INP như sau:

10

10 100 20 1 2 50 70 80 3 60

- thì Output phải là:

1 2 50 70 80

ý tưởng của thuật toánquy hoạch động ở đây là: Để xây dựng dãy con dài nhất của dãy đã cho chúngta sẽ xây dựng dãy con dài nhất của đoạn phần tử đầu a1, a2, ai

Để làm được điều đó: ta gọi S[i] là số lượng phần tử nhiều nhất của dãycon tăng dần, trong đó ai cũng thuộc dãy con trên (nó là phần tửcuối cùng)

Chúng ta sẽ tính S[i] ở từng bước dựa vào các S[i-1], S[1] như sau:

Trang 2

S[i]:=Max(S[j]+1) với j=i-1, 1 mà aj < ai.

Để lấy lại dãy con cực đại ta dùng một mảng Truoc với ý nghĩa: Truoc[i]là chỉ số của phần tử trước phần tử i trong dãy con cực đại lấy trong dãy a1,a2, ai

Bây giờ chúng ta phải tìm vị trí i sao cho S[i] đạt max Ta lưu vị trí đóvào biến Luu

Như vậy: S[Luu] chính là số lượng phần tử của dãy con cực đại của dãy đãcho Và bằng mảng Truoc ta có thể lấy lại chỉ số các phần tử thuộc dãy con đó

Đến đây ta gặp một vấn đề: Mảng Truoc chỉ cho phép ta lần ngược từ cuốivề đầu dó đó

để in ra các chỉ số theo thứ tự tăng dần ta phải dùng thêm mộtmảng phụ P và in ngược lại của mảng P:

dem:=0;

i:=Luu;

While i<>0 do

Begin

Inc(dem);P[dem]:=i;i:=Truoc[i];

End;

Chỉ số theo thứ tự tăng dần của dãy con cực đại được in ra bằng dònglệnh:

For i:=dem downto 1 do Write(P[i],' ');

Tuy nhiên làm như trên có vẻ dài dòng trong khi chúng ta đã nhận ra tínhđệ quy trong việc lấy ngược lại Và thủ tục in ra dãy con đã rất ngắn gọn vàsáng sủa:

Procedure Print(i:Integer);

Begin

If i>0 then

Begin

Print(Truoc[i]);Write(i,' ');

End;

End;

Trang 3

Công việc in ra chỉ cần một lời gọi: Print(Luu);

Ta có toàn văn chương trình:

{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+,Y+} {$M 65500,0,655360}

Uses Crt;

Const fi = 'DAYSO.INP';

MaxN=5000;

Var A : Array[1 MaxN] ofInteger;

S :Array[1 MaxN] of Integer;

Truoc : Array[1 MaxN]of Integer;

i,j,Luu : Word;

N : Word;

Procedure Init;

Begin

Fillchar(S,SizeOf(S),1);

Fillchar(Truoc,SizeOf(Truoc),0);

End;

Procedure Readfile;

Var f:Text;

Begin

Assign(f,fi);

Trang 4

For i:=1 to N do Read(f,A[i]); Close(f);

End;

Procedure Find;

Begin

For i:=2 to N do

Begin

For j:=i-1 downto 1 do

If (A[j]< and (S[i]

Begin

S[i]:=S[j]+1;

Truoc[i]:=j;

End;

End;

End;

Procedure Print(i:Word); Begin

If i >0 then

Begin

Print(Truoc[i]);

Write(a[i],' ');

End;

End;

Trang 5

Procedure OutputResult;

Begin

Luu:=N;

For i:=N-1 downto 1 do

If S[i]>S[Luu] then Luu:=i;

Print(Luu);

End;

BEGIN

Clrscr;

Init;

Readfile;

Find;

OutputResult;

Readln;

END

Qua ví dụ trên chúng ta đã hiểu cách mà thuật toán thể hiện Bây giờchúng ta sẽ xét tiếp một bài toán sắp xếp trình tự phục vụ khách hàng mà cáchgiải đều sử dụng thuật toán Quy hoạch động trên mảng một chiều

Ta xét tiếp mộtví dụ sau:

Bài toán 2: Tại thời điểm 0, ôngchủ một máy tính hiệu năng cao nhận được đơn đặt hàng

thuê sử dụng máy của nkhách hàng Các khách hàng được đánh số từ 1 đến n Khách hàng i cần sử dụngmáy từ thời điểm di đến thời điểm ci (di, cilà các số nguyên và 0 < di <

ci < 1000000000) và sẽ trả tiền sử dụng máy là pi (pi nguyên, 0 < p i ≤ 10000000) Bạn cần xác định xem ông chủ cần nhận phục vụ những khách hàng nào sao cho khoảng thời

Trang 6

Dòng đầu tiên ghi số n (0 < n =< 1000);

- Dòng thứ i+1 trong số n dòng tiếp theo ghi 3 số di, ci,pi cách nhau bởi dấu trắng (i = 1, 2, n)

Kếtquả: Ghi ra file văn bản THUE.OUT

-Dòng đầu tiên ghi hai số nguyên dương theo thứ tự là số lượng khách hàngnhận phục vụ

và tổng tiền thu được từ việc phục vụ họ

-Dòng tiếp theo ghi chỉ số của các khách hàng được nhận phục vụ

Ví dụ:

3

150 500 150

1 200 100

400 800 80

2 180

2 3

4

400 821 800

200 513 500

100 325 200

600 900 600

2 1100

2 4

Bài toán nàychúng ta phải chú ý ở chỗ: Để dùng thuật toán Quy hoạch động tối ưu từng bướcthì trước hết chúng ta phải sắp xếp các ci theo thứ tự tăng dần:

Giả sử c1 ≤ c2 ≤ ≤ cN

Tương tự bàitoán trên: Gọi F[k] là số tiền lớn nhất khi phục vụ một số khách hàng từ 1 đếnk

Với mỗi F[k] tacó:

- Nếu chấp nhận phục vụ khách k thìF[k]:=F[t]+pk (với t là chỉ số max thoả mãn khoảng thời gian [dt, ct [dk,ck]= )

- Nếu không chấp nhận phục vụ k thì F[k]:=F[k-1]

Như vậy hàm quyhoạch động của F[k] sẽ là:

F[k]:=Max{F[t]+pk,F[k-1]} với k = 2, 3, N và t có ý nghĩa như trên

Trang 7

Để lấy lại chỉ số các khách hàngđược phục vụ chúng ta lại dùng mảng Truoc như ví dụ trên

Trên đây là những gì tôi muốn trìnhbày với các bạn Theo tôi, thuật toán tuy đơn giản nhưng tầm ứng dụng của nórất phong phú mà nếu nắm vững nó là rất có lợi cho tư tưởng thuật toán của cácbạn

Ngày đăng: 11/09/2012, 15:25

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w