Đề bài: http://vn.spoj.com/problems/MPILOT/
Thuật toán:
- Đây là bài tập về thuật toán Heap cơ bản
- Ta đưa yêu cầu bài toán thành chọn các lái phụ có chênh lệch giữa lương lái chính và lương lái phụ là lớn nhất mà vẫn đảm bảo yêu cầu có thể ghép được n/2 cặp mà tuổi lái phụ < lái chính
- Heap sẽ lưu độ chênh lệch giữa lương lái phục và chính của mọi người
- Duyệt i=1..n, đẩy i vào, nếu i lẻ thì lấy ở heap ra 1 thằng làm lại phụ
- Các bạn hãy đọc code để rõ hơn
Code: [xem code]
const fi='';
fo='';
maxn=10000+3;
var p,h:array[1..maxn] of longint;
i,j,n,res,sum:longint;
a,c:array[1..maxn] of longint;
nh:longint;
procedure enter;
begin
assign(input,fi);reset(input);
readln(n);
for i:=1 to n do read(a[i],c[i]);
close(input);
end;
procedure swap(var x,y:longint);
var tg:longint;
begin
tg:=x;x:=y;y:=tg;
end;
function tinh(x:longint):longint;
begin
exit(a[x]-c[x]);
end;
procedure downheap(i:longint);
var j:longint;
begin
j:=i + i;
if j>nh then exit;
if (j tinh(h[j]) ) then inc(j);
if tinh(h[i]) < tinh(h[j]) then
begin
swap(h[i],h[j]);
downheap(j);
end;
end;
procedure upheap(i:longint);
var j:longint;
begin
j:= i div 2;
if i>1 then
if tinh(h[i]) > tinh(h[j]) then
begin
swap(h[i],h[j]);
upheap(j);
end;
end;
function pop:longint;
begin
pop:=h[1];
h[1]:=h[nh];
dec(nh);
downheap(1);
end;
procedure push(i:longint);
begin
inc(nh);
h[nh]:=i;
upheap(nh);
end;
procedure process;
begin
for i:=1 to n do
begin
inc(sum,a[i]);
push(i);
if i mod 2 = 1 then inc(res,tinh(pop) );
end;
end;
procedure print;
begin
assign(output,fo);rewrite(output);
writeln(sum-res);
close(output);
end;
begin
enter;
process;
print;
end.
cho em hỏi tại sao phải i mod 2=1, em ko hiểu chỗ đó
Mỗi khi heap có lẻ phi công (i mod 2 = 0) thì mình phải lấy ra ngay thằng tốt nhất để làm lái phụ. Nếu mà không lấy ra ngay thì sẽ không thỏa mãn điểu kiện tuổi lái chính > tuổi lái phụ.
Bạn nên nhớ đề bài có đoạn “Các phi công sắp tăng dần theo tuổi.”
Bạn suy nghĩ thêm nhé…