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

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

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

Thông tin tài liệu

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

Thuật toán quy hoạch động trên mảng một chiềuTrần Minh QuangBà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:1010 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:Ban đầu S[i] với i = 1, 2, . N được gán bằng 1 vì trường hợp xấu nhấtthì dãy con chỉ là một phần tử.Với mỗi i >= 2 thì S[i] được tính bằng công thức truy hồi sau: 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 doBeginInc(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);BeginIf i>0 thenBeginPrint(Truoc[i]);Write(i,' ');End;End; 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;BeginFillchar(S,SizeOf(S),1);Fillchar(Truoc,SizeOf(Truoc),0);End;Procedure Readfile;Var f:Text;BeginAssign(f,fi);Reset(f);Readln(f,N); For i:=1 to N do Read(f,A[i]);Close(f);End;Procedure Find;BeginFor i:=2 to N doBeginFor j:=i-1 downto 1 doIf (A[j]< and (S[i] BeginS[i]:=S[j]+1;Truoc[i]:=j;End;End;End;Procedure Print(i:Word);BeginIf i >0 thenBeginPrint(Truoc[i]);Write(a[i],' ');End;End; Procedure OutputResult;BeginLuu:=N;For i:=N-1 downto 1 doIf S[i]>S[Luu] then Luu:=i;Print(Luu);End;BEGINClrscr;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 gian sử dụng máy của hai khách được nhận phục vụ bất kỳkhông được giao nhau đồng thời tổng tiền thu được từ việc phục vụ họ là lớnnhất.Dữliệu vào: Từ file văn bản THUE.INP 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ụ:THUE.INP THUE.OUT THUE.INP THUE.OUT3150 500 1501 200 100400 800 802 1802 34400 821 800200 513 500100 325 200600 900 6002 11002 4Bà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. Để 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. . Thuật toán quy hoạch động trên mảng một chiềuTrần Minh QuangBà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á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

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

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan