哎,昨天好怠惰只想玩……結果對着一道高精度看了半天覺得自己還是算了吧hhh
今天起來就沒有看那道高精度……雖然知道基本思想是什麼但是不會寫……於是寫了一道水題,基本就是找規律+遞歸,沒什麼技術難度(廢話有技術難度的題目並不會寫==)
洛谷P1011 車站
題目描述
火車從始發站(稱爲第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
怎麼說呢第一眼看上去,既然有“前兩站之和”那麼就是說有斐波那契的影子。這一題好的地方在於它下車的人數等於上一次上車的人數。那麼也就是說:
本次車上增加的人數=(n-1站上車)+(n-2站上車)-(n-1站上車)=(n-2站上車)
於是我們用題中的數據列一個表
(m=32,a=5)
人數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
上車 | 5 | p | 5+p | 5+2P | 10+3p | 15+5p | 0 |
下車 | 0 | p | p | 5+p | 5+2p | 10+3p | 0 |
車上 | 0 | 5 | 10 | 10+p | 15+2p | 20+4p | 32 |
0 | 5 | 5 | p | p | 2p |
於是就很好懂了,也就是:
我們在這裏再考慮進第一次上車的人,因爲之後增加的人不是以第一次上車的人數p來作爲基準。第二次上車時上車的人數是第一次加上第二次,也就是a+p。如果我們把上車下車的人分成第一次上車人數a以及p兩部分來求,我們很容易發現一個規律,那就是:
由於a是常數增長的,
也就意味着:
如果我們累加一下,那這題就是一個簡單的Fibonacci數列求和之後解方程組。由於f這種Fibonacci 增長從第三站開始(第二次下車後)所以到第四站的時候車上人數纔開始滿足這種規律。
於是由題意得在第x站的人數爲:
到倒數第二站就有
於是就懟出來了。
//////////////////////////////////
//
//By frostwing98
//17.7.28
//
//////////////////////////////////
#include <iostream>
#define MAX 20
using namespace std;
long fibo(int n)
{
if (n == 1 || n == 2)
return 1;
else
return fibo(n - 1) + fibo(n - 2);
}
long fiboSum(int n){
long sum=0;
for (int i = 1; i <= n; i++)
{
sum += fibo(i);
}
return sum;
}
int main(void)
{
long a, n, m, x;
cin >> a >> n >> m >> x;
long p = 0;
if (n > 4)
{
p = (m - a*(n - 3));
p /= fiboSum(n - 4);
}
if (x <= 3)
cout << a*(x - 1);
else
{
long number = a*(x - 2) + p*fiboSum(x - 3);
cout << number;
}
return 0;
}