Đề bài: http://vn.spoj.com/problems/COIN34/
Thuật toán:
- Bài này đơn thuần sử dụng thuật toán duyệt phân tập.
- Các bạn có thể tham khảo tài liệu về thuật toán duyệt phân tập tại: http://yeulaptrinh.de/315/thuat-toan-duyet-phan-tap/
Code:
uses math;
const
fi='';
fo='';
maxs=2*trunc(1e6);
maxn=17;
var
st,d : array[1..maxs] of longint;
c : array[1..maxn*2] of longint;
i,j,n,res,s1,s2,x,d1,c1,top : longint;
procedure enter;
begin
assign(input,fi);reset(input);
assign(output,fo);rewrite(output);
c[1] :=2; c[2] := 3; c[3] := 5;
for i:=4 to 34 do
c[i] := c[i-1]+c[i-2]+c[i-3];
end;
procedure up1;
begin
//if c1=x then begin res := max(res,d1); exit; end;
//if c1>x then exit;
inc(top); st[top] := c1;
d[top] := d1;
end;
procedure try1( i : longint);
var j : longint;
begin
for j:=0 to 1 do
begin
if j=1 then begin c1 := c1+c[i]; inc(d1) end;
if i=s1 then up1 else try1(i+1);
if j=1 then begin c1 := c1-c[i]; dec(d1) end;
end;
end;
procedure up2;
var dau,cuoi,giua,xx : longint;
begin
if x=c1 then begin res := max(res,d1); exit; end;
if c1>x then exit;
xx := x-c1;
dau:=1;cuoi:=top;
giua:=(dau+cuoi) div 2;
while (giua<>dau) and (giua<>cuoi) do
begin
if st[giua]>=xx then cuoi :=giua else dau := giua;
giua :=(dau+cuoi) div 2;
end;
for giua := dau to cuoi do
if st[giua]=xx then break;
if st[giua]=xx then res := max(res,d1+d[giua]);
end;
procedure try2( i :longint);
var j : longint;
begin
for j:=1 downto 0 do
begin
if j=1 then begin c1 := c1+c[i]; inc(d1); end;
if i=34 then up2 else try2(i+1);
if j=1 then begin c1 := c1-c[i]; dec(d1); end;
end;
end;
procedure swap(var x,y : longint);
var tg : longint;
begin
tg:=x;x:=y;y:=tg;
end;
procedure qs1(l,r : longint);
var i,j,x,y : longint;
begin
i :=l;j:=r;
x:=st[(l+r) div 2];
y:=d[(l+r) div 2];
repeat
while (x>st[i]) or((x=st[i]) and (d[i]>y)) do inc(i);
while (xj;
if i
[…] COIN34 – SPOJ […]