問題 L: 火車站
時間限制: 1 Sec 內存限制: 128 MB提交: 13 解決: 7
[提交][狀態][討論版]
題目描述
火車從始發站(稱爲第1站)開出,在始發站上車的人數爲a,然後到達第2站,在第2站有人上、下車,但上、下車的人數相同,因此在第2站開出時(即在到達第3站之前)車上的人數保持爲a人。從第3站起(包括第3站)上、下車的人數有一定規律:上車的人數都是前兩站上車人數之和,而下車人數等於上一站上車人數,一直到終點站的前一站(第n-1站),都滿足此規律。現給出的條件是:共有N個車站,始發站上車的人數爲a,最後一站下車的人數是m(全部下車)。試問x站開出時車上的人數是多少?
輸入
輸入包含一行, 有四個正整數:a(a<=100),n(n<=20),m(m<=10000)和x(x<=19)
輸出
輸出爲一個整數,爲x站開出時車上的人數。
樣例輸入
1 6 7 4
樣例輸出
4
剛剛開始我wa了好幾次,然後就去找博客看,結果發現大多數寫的都很複雜,亂七八糟的索性不看,回過頭重新看題目發現是自己理解錯了。。。
在自己重新推倒之後,發現這就是多個Fibonacci數列的和。。。我設第二次上車的人數爲‘z’,仔細觀察其實每次上下車的人數其實就是關於z和a的Fibonacci數列的和。
z ( 1 ) = 0 , z ( 2 ) = 1 , z ( 3 ) = 1 , z ( 4 ) = 2 ..............
a ( 1 ) = 1 , a ( 2 ) = 0 , a ( 3 ) = 1 , a ( 4 ) = 1 ..............
#include <iostream>
#include <cstring>
using namespace std;
int dp[25],z[25],A[25];
int main()
{
int a,n,m,x;
z[1]=0,A[1]=1;
z[2]=1,A[2]=0;
for(int i=3;i<=25;i++) //爲了避免多餘的運算,就在while循環的外面計算了除了所有的A與z的數列(這裏的z是小寫的)。
{
A[i]=A[i-1]+A[i-2];
z[i]=z[i-1]+z[i-2];
}
while(cin>>a>>n>>m>>x)
{
int Z; //我這裏建立的變量是大寫的Z的大家看到下面的時候注意一下。
memset(dp,0,sizeof(dp));
dp[1]=dp[2]=a;
dp[3]=dp[2]+a;
dp[n]=m;
int sum1=0,sum2=0;
for(int i=3;i<n;i++)
{
sum1=sum1+z[i]-z[i-1];
sum2=sum2+A[i]-A[i-1];
}
Z=(m-a-sum2*a)/(sum1); //在這裏求出Z。
for(int i=3;i<=x;i++)
{
dp[i]=dp[i-1]+(z[i]-z[i-1])*Z+(A[i]-A[i-1])*a; //然後計算我們需要的答案
}
cout<<dp[x]<<endl;
}
return 0;
}