Cho 4 loại đoạn thẳng sơn các màu xanh dài dx, đỏ dài dd, tím dài dt và vàng dài dv. Các đoạn thẳng cùng màu thì có cùng chiều dài và số lượng không hạn chế. Hãy chọn ra không quá N đoạn thẳng rồi xếp nối nhau theo chu vi để thu được một hình chữ nhật có diện tích lớn nhất với các cạnh lần lượt mang các màu theo chiều quay của kim đồng hồ là xanh, đỏ, tím, vàng. Dữ liệu trong bài đều là các số nguyên dương.
35 3 2 2 5 480 8 10 12 4 Dòng thứ nhất: số N > 0. Dòng thứ hai: bốn số dx dd dt dv Dữ liệu ra: tệp văn bản XDTV2.OUT
Dịng đầu tiên: Diện tích của hình chữ nhật xanh - đỏ - tím - vàng.
Dòng thứ hai: 4 số cho biết số lượng đoạn thẳng cần chọn theo mỗi loại màu để ghép được hình chữ nhật diện tích max.
Kết quả trên cho biết cần chọn 8 đoạn xanh, 10 đoạn đỏ, 12 đoạn tím và 4 đoạn vàng để ghép thành hình chữ nhật có diện tích max là 480.
Thuật toán
Phương pháp: Tham.
Tương tự như bài Xanh đỏ tím vàng 1, trước hết ta tính các bộ xanh - tím (nx,nt) và bộ đỏ - vàng (nd, nv). Tiếp đến ta tính xem khi lấy i bộ xanh – tím để kết hợp với j bộ đỏ - vàng thì thu được hình chữ nhật có diện tích max là bao nhiêu. Lưu ý rằng i bộ xanh - tím sẽ gồm i(nx+nt) đoạn thẳng. Số đoạn thẳng cịn lại khi đó sẽ là N – i(nx+nt). Số này sẽ tạo ra được j = (N – i(nx+nt)) / (nd+nv) bộ đỏ - vàng.
Độ phức tạp: O(n).
(* Pascal *)
(****************************************** Xanh Do Tim Vang 2
******************************************) program xdtv2; uses crt; const fn = 'xdtv2.inp'; gn = 'xdtv2.out'; bl = #32; var n: longint; f,g: text; x,d,t,v: longint; dx,dd,dt,dv: longint; nx,nt,nd,nv: longint; smax,bmax: longint; procedure Doc: Tự viết;
function Ucln(a,b: longint): Tự viết; function Bcnn(a,b: longint): Tự viết; function Min(a,b: longint): Tự viết;
(*--------------------------------------------------------- 1 bo xanh - tim = (sx,st) = (so doan xanh, so doan tim) sx = bcnn(dx,dt) div dx st = bcnn(dx,dt) div dt bxt = sx + st --------------------------------------------------------*) procedure XuLi; var b: longint; bxt, bdv: longint; s: longint; sx,st, sd, sv: longint; begin b := bcnn(dx,dt);
sx := b div dx; st := b div dt; bxt := sx + st; b := Bcnn(dd,dv); sd := b div dd; sv := b div dv; bdv := sd + sv; smax := 0; bmax := 0; for b := 1 to ((n - bdv) div bxt) do begin s := (b*sx*dx)*(((n – b*bxt) div bdv)*sd*dd); if (s > smax) then
begin bmax := b; smax := s; end; end;
nx := bmax * sx; nt := bmax * st;
b := smax div (nx*dx); { Chieu dai canh Do ( = Vang) } nd := b div dd; nv := b div dv;
end;
procedure Ghi: Tự viết; BEGIN
Doc; XuLi; Ghi; END. // C# using System; using System.IO; using System.Collections; /*=============================================== Xanh Do Tim Vang 2 ===============================================*/ namespace SangTao2 {
class Xdtv2 { static int n;
static int dx, dd, dt, dv;
static int nx, nd, nt, nv; // Dap so: so luong moi loai const string fn = "xdtv1.inp";
const string gn = "xdtv1.out"; static void Main(string[] args){ Doc(); XuLi(); Ghi();
XemKetQua(); Console.WriteLine("\n Fini"); Console.ReadLine();
}
static public void Doc(){
int[] a = Array.ConvertAll(File.ReadAllText(fn). Split(new chae[] {' ','\n','\r','\t'}, StringSplitOptions.RemoveEmptyEntries), new Converter<string, int>(int.Parse)); int j = 0;
n = a[j++]; dx = a[j++]; dd = a[j++]; dt = a[j++]; dv = a[j];
} // Doc
static public void XuLi() { int b = Bcnn(dx,dt);
int sx = b / dx; // so luong doan xanh trg 1 bo XT int st = b / dt; // so lg doan tim trg 1 bo X-T int sxt = sx+st; // tg so doan xanh va tim trg bo XT
b = Bcnn(dd,dv);
int sd = b / dd, sv = b / dv; // do, vang
int sdv = sd + sv;// tg so doan do va vg trg bo DV int smax = 0; // dt max
int bxtmax = 0; // so bo XT toi da
int bb = (n-sdv)/sxt; // can tren cua cac bo XT for (b = 1; b <= bb; ++b) { // b - so bo XT
int s = (b*sx*dx)*(((n-b*sxt)/sdv)*sd*dd);// dt if (s > smax) { bxtmax = b; smax = s; }
}
nx = bxtmax * sx; nt = bxtmax * st;
b = smax / (nx * dx); // chieu dai canh Do = Vang nd = b/dd; nv = b/dv;
} // XuLi
static public int Ucln(int a, int b): Tự viết; static public int Bcnn(int a, int b): Tự viết; static public int Min(int a,int b): Tự viết; static public void Ghi(): Tự viết;
static public void XemKetQua(): Tự viết; }// Xdtv2
} // SangTao2