洛谷 P1011车站题解--zhengjun
题目描述
火车从始发站(称为第\(1\)站)开出,在始发站上车的人数为\(a\),然后到达第\(2\)站,在第\(2\)站有人上、下车,但上、下车的人数相同,因此在第\(2\)站开出时(即在到达第\(3\)站之前)车上的人数保持为\(a\)人。从第\(3\)站起(包括第\(3\)站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第\(n-1\)站),都满足此规律。现给出的条件是:共有\(N\)个车站,始发站上车的人数为\(a\),最后一站下车的人数是\(m\)(全部下车)。试问\(x\)站开出时车上的人数是多少?
输入格式
\(a\)(≤20),\(n\)(≤20),\(m\)(≤2000),和\(x\)(≤20),
输出格式
从\(x\)站开出时车上的人数。
输入输出样例
输入 #1 复制
5 7 32 4
输出 #1 复制
13
思路
直接先列个表来找找规律。
数据 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
上车人数 | a | b | a+b | a+2b | 2a+3b | 3a+5b | 5a+8b |
下车人数 | 0 | b | b | a+b | a+2b | 2a+3b | 3a+5b |
开始时车内人数 | a | a | 2a | 2a+b | 3a+2b | 4a+4b | 6a+7b |
这样可能还是找不到规律。我们把a,b换掉,用它们的系数表示。 | |||||||
数据 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
:-- | -- | -- | -- | -- | -- | -- | -- |
上车人数 | 1 | 1 | 1+1 | 1+2 | 2+3 | 3+5 | 5+8 |
下车人数 | 0 | 1 | 1 | 1+1 | 1+2 | 2+3 | 3+5 |
开始时车内人数 | 1 | 1 | 2 | 2+1 | 3+2 | 4+4 | 6+7 |
这还不够明显吗。 | |||||||
数据 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
:-- | -- | -- | -- | -- | -- | -- | -- |
上车人数 | 1 | 1 | 2 | 3 | 5 | 8 | 13 |
下车人数 | 0 | 1 | 1 | 2 | 3 | 5 | 8 |
开始时车内人数 | 1 | 1 | 2 | 3 | 5 | 8 | 13 |
斐波那契数列!!
那么,我们用\(f\)数组来计算斐波那契数列。
\(f[1]=1;f[2]=1;f[3]=2;f[4]=3;f[5]=5;f[6]=8...\)
看表可知:
- 第 \(i\) 站的上车人数\(=f[i-2]\times a+f[i-1]\times b\) (\(i\ge 2\) )
- 第 \(i\) 站的下车人数\(=f[i-3]\times a+f[i-2]\times b\) (\(i\ge 3\) )
- 第 \(i\) 站的开始时车内人数
\(=\)\(\sum_{k=1}^{i}\)(第\(k\)站上车人数\(-\)第\(k\)站下车人数)(可以抵消)
\(=\)第\(i\)站上车人数\(+a-b\)
\(=f[i-2]\times a+f[i-1]\times b+a-b\)
\(=(f[i-2]+1)\times a+(f[i-1]-1)\times b\)(\(i\geq 2\) )
所以,我们只要一步一步推下来,推到\(n\),再根据\(m\)和\(a\)算出\(b\),再求出第\(x\)站开始时的人数就可以了。
注意:题中的\(m\)应该是第\(n\)站开始时的人数
以下是样例:
数据 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
上车人数 | 5 | b | 5+b | 5+2b | 10+3b | 15+5b | 0 |
下车人数 | 0 | b | b | 5+b | 5+2b | 10+3b | 32 |
开始时车内人数 | 5 | 5 | 10 | 10+b | 15+2b | 20+4b | 32 |
也就是 第六站开始时的人数 \(=m\)
即 \((f[i-2]+1)\times a+(f[i-1]-1)\times b=m\)
所以 \(b=\frac {m-(f[i-2]+1)\times a } { f[i-1]-1 }=\frac {32-(3+1)\times 5}{5-1}=3\) 。
那么 第\(4\)站开始时的人数
\(=\)第\(i\)站上车人数\(+a-b\)
\(=(f[i-2]+1)\times a+(f[i-1]-1)\times b\)
\(=(f[2]+1)\times a+(f[3]-1)\times b\)
\(=(1+1)\times 5+(2-1)\times 3\)
\(=13\)
不就了事了吗
我感觉讲的够详细了。
最后,特判一下 \(x=1\) 时的情况,直接输出 \(a\) 。
代码
#include<bits/stdc++.h>
int f[25]={0,1,1};
int n,m,a,b,x;
int main(){
scanf("%d%d%d%d",&a,&n,&m,&x);
for(int i=3;i<=n;i++)
f[i]=f[i-1]+f[i-2];
b=(m-f[n-1-2]*a-a)/(f[n-1-1]-1);//是第(n-1)个点的开始为m,套用公式
if(x==1)//特判
printf("%d",a);
else
printf("%d",(f[x-2]+1)*a+(f[x-1]-1)*b);//套公式
return 0;
}