您的位置:首页 > 其它

jzoj P3769 A+B___dfs+规律

2018-02-03 16:20 393 查看

题目大意:

对于每个数字x,我们总可以把它表示成一些斐波拉切数字之和,比如8 = 5 + 3, 而22 = 21 + 1,因此我们可以写成 x = a1 * Fib1 + a2 * Fib2 + a3 * Fib3 + … + an * Fibn, 其中,Fib1 = 1, Fib2 = 2…. Fib[i] = Fib[i – 1] + Fib[I - 2], 且a
> 0.那么我们称ai为x的一种斐波拉切表示,由于表示方法有很多种,我们要求最大化a[1…n],即,如果b[1…n]和a[1…m]都可以表示x,若m > n 则a更大,若 m = n, 则从高位到低位比,第一个不同处i,若ai > bi 则a比b大。

你的任务很简单,给你两个用斐波拉切数最大化表示的两个数字,输出他们相加后用斐波那契最大化表示的数字。

对于30%的数据 长度 <= 1000

对于100%的数据 长度 <= 1000000

题解:

这题其实特别的神奇…

是需要找规律的,当然对于直接高精度的dalao们,我当然是膜拜辣。。

我们先列出一副符合题目的斐波那契数列(从1,2开始):

序1 2 3 4 5 6

fi 1 2 3 5 8 13

A 0 1 0 1

B 0 1 0 0 1

C 0 2 0 1 1

我们考虑C=A+B的情况

此时的C如果化简,我们发现任意一个ai必定为0或1!这个在草稿纸上随便推一下应该都知道的..

对于C上某一位:

①>=1,则我们可以发现,

因为一个直观的斐波那契数列公式是

fi=fi-1+fi-2]

则当f[i]>=1且f[i-1]>=1时我们直接将能使用的对数k递归到f[i+1]去重复进行①②操作

可知k=min{fi,fi-1}

②>=2,则我们推演一下:

F[i-1]+F[i]=F[i+1]

F[i-1]+F[i-2]+F[i]=F[i+1]+F[i-2]

2F[i]=F[i+1]+F[i-2]

那我们可以得出,每2个fi就可以【分解成】1个f[i-2]和一个f[i+1],此时我们能分多少对就分多少对过去然后递归过去,然后重复进行①②操作

代码:

var
ans,a,b:array [-100..1000100] of longint;
i,j,k,n,m,z:longint;

procedure dfs(dep,x:longint);
var
k:longint;
begin
ans[dep]:=ans[dep]+x;
if ans[dep-1]>=1 then
if ans[dep]>=1 then
begin
if ans[dep-1]>ans[dep]
then k:=ans[dep]
else k:=ans[dep-1];
ans[dep]:=ans[dep]-k;

f333
ans[dep-1]:=ans[dep-1]-k;
dfs(dep+1,k);
end;
if ans[dep]>=2 then
begin
k:=ans[dep] div 2;
ans[dep]:=ans[dep] mod 2;
if dep<=2
then dfs(dep-1,k)
else dfs(dep-2,k);
dfs(dep+1,k);
end;

end;

begin
read(n);
for i:=1 to n do read(a[i]);
readln;
read(m);
for j:=1 to m do read(b[j]);
if n>m then z:=n
else z:=m;
z:=z+50;
for i:=1 to z do
ans[i]:=a[i]+b[i];
for i:=1 to z do
begin
if ans[i-1]>=1 then
if ans[i]>=1 then
begin
if ans[i-1]>ans[i]
then k:=ans[i]
else k:=ans[i-1];
ans[i]:=ans[i]-k;
ans[i-1]:=ans[i-1]-k;
dfs(i+1,k);
end;
if ans[i]>=2 then
begin
k:=ans[i] div 2;
ans[i]:=ans[i] mod 2;
if i<=2
then dfs(i-1,k)
else dfs(i-2,k);
dfs(i+1,k);
end;
end;
while ans[z]=0 do dec(z);
write(z,' ');
for i:=1 to z do write(ans[i],' ');
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: