51nod1149 Pi的遞推式

 

基準時間限制:1 秒 空間限制:131072 KB 分值: 640
F(x) = 1 (0 <= x < 4)
F(x) = F(x - 1) + F(x - pi) (4 <= x)
Pi = 3.1415926535.....
現在給出一個N,求F(N)。由於結果巨大,只輸出Mod 10^9 + 7的結果即可。
 
Input
輸入一個整數N(1 <= N <= 10^6)
Output
輸出F(N) Mod 10^9 + 7
Input示例
5
Output示例
3

 

數學問題 遞推 組合數

實數下標的遞推,甚至不能記憶化(吧?),遞歸顯然不可取。

可以先考慮一般的情況。

比如Fibonacci數列的遞推式是 $ F[n]=F[n-1]+F[n-2] $ 

衆所周知,它的組合數意義可以解釋爲任選走一級或走兩級,從0級上到n級臺階的方案數。(然而蒟蒻博主就不知道)

由此得出F[n]的另一個計算方式是枚舉走兩級走了i次,然後 $F[n]=\sum_{i=0}^{n/2} C(n-2i+i,i) $

這個算法可以推廣到一般的遞推式。

那麼在本題中,可以類似地枚舉走1和走pi的次數,累計從0走到大於n-4的位置的方案數。

由於枚舉走1或枚舉走pi時,另一個走法的次數上限不同(第一次到達>n-4的位置時,到達的具體位置不同),所以要分類討論。

 

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<cmath>
 6 #define LL long long
 7 using namespace std;
 8 const double pi=acos(-1.0);
 9 const int mxn=1000010;
10 const int mod=1e9+7;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
15     return x*f;
16 }
17 int ksm(int a,int k){
18     int res=1;
19     while(k){
20         if(k&1)res=(LL)res*a%mod;
21         a=(LL)a*a%mod;
22         k>>=1;
23     }
24     return res;
25 }
26 int fac[mxn],inv[mxn];
27 void init(int ed){
28     fac[0]=fac[1]=1;inv[0]=inv[1]=1;
29     for(int i=2;i<=ed;i++)
30         fac[i]=(LL)fac[i-1]*i%mod;
31     inv[ed]=ksm(fac[ed],mod-2);
32     for(int i=ed-1;i;i--)
33         inv[i]=(LL)inv[i+1]*(i+1)%mod;
34     return;
35 }
36 inline int C(int n,int m){
37     if(n<m)return 0;
38     return (LL)fac[n]*inv[m]%mod*inv[n-m]%mod;
39 }
40 int n;
41 int ans=0;
42 int main(){
43     int i,j;
44     n=read();
45     if(n<4){
46         printf("1\n");return 0;
47     }
48     init(n);
49     for(i=0;i<=n-4;i++){//1
50         int tmp=(int)(((double)n-4-i)/pi);
51 //        printf("i:%d tmp:%d %d\n",i,tmp,C(tmp+i,i));
52         (ans+=C(tmp+i,i))%=mod;
53     }
54     for(i=0;i*pi<=n-4;i++){//pi
55         int tmp=(int)(n-4-i*pi);
56 //        printf("i:%d tmp:%d %d\n",i,tmp,C(tmp+i,i));
57         (ans+=C(tmp+i,i))%=mod;
58     }
59     printf("%d\n",ans);
60     return 0;
61 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章