zoukankan      html  css  js  c++  java
  • 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
    ");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
    ",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
    ",i,tmp,C(tmp+i,i));
    57         (ans+=C(tmp+i,i))%=mod;
    58     }
    59     printf("%d
    ",ans);
    60     return 0;
    61 }
  • 相关阅读:
    关于做项目
    不一样的Android studio
    你认为一些军事方面的软件系统采用什么样的开发模型比较合适?
    关于Android studio
    面向对象建模所用图的简单总结
    浅谈Android 01
    用例图与类图的联系与区别
    面向过程(或者叫结构化)分析方法与面向对象分析方法到底区别在哪里?请根据自己的理解简明扼要的回答。
    你认为一些军事方面的软件系统采用什么样的开发模型比较合适?
    项目答辩后的感想
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/7097092.html
Copyright © 2011-2022 走看看