#include
using namespace std;
int main()
{
int a,n,m,x,b;
int fibbonaci[20]= {0,1,0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610};
cin>>a>>n>>m>>x;
b=(m-a*(fibbonaci[n-1]+1))/(fibbonaci[n]-1);
cout<<(fibbonaci[x]+1)*a+(fibbonaci[x+1]-1)*b;
return 0;
}
分析:
设up[i]为i站的上车人数、down[i]为i站的下车人数、p[i]为i站开出时车上的人数(1≤i≤n)。初始时up[1]=p[1]=a,down[1]=0。
①依次枚举第2站的上车人数为1,2,……
设第2站的上车人数为k
up[2]=down[2]=k,p[2]=p[1]+up[2]-down[2]=a
②按照下式递推第3站…第n-1站的车上人数
up[i]=up[i-1]+up[i-2]
down[i]=up[i-1]
p[i]=p[i-1]+up[i]-down[i]=p[i-1]+up[i-2] (3≤i≤n-1)
③计算从x站开出时车上的人数
若p[n-1]=m,则输出p[x];否则k←k+1,返回①…,直至p[n-1]>m为止。因为p相对k是递增的,因此在当前p[n-1]>m的情况下,无论k值怎样增加也不会使得p[n-1]=m的。
源程序如下:
const maxn=100
var
a,n,m,x ,k,i:integer;
p,down,up:array[1..maxn] of integer;
begin
readln(a,n,m,x);
fillchar(p,sizeof(p),0);
up[1]:=a;down[1] :=0;p[1] :=a;
k:=1;n:=n-1;
repeat
up[2]:=k;down[2]:=k;p[2]:=p[1];{枚举第2站的上车人数、下车人数和车上人数}
for i:=3 to n do begin {递推第3站…第n-1站的车上人数}
up[i] :=up[i-1]+up[i-2];
down[i] :=up[i-1];
p[i] :=p[i-1]+up[i-2];
end;
if p[n]=m then {若n站下车的人数为m,则输出从x站开出时车上的人数,并退出}
begin
writeln(p[x]);
readln;
exit;
end;
k:=k+1;{第2站上车人数增加1}
until p[n]>m;{直至无法满足此规律为止}
writeln('No Answer.');
end.