zoukankan      html  css  js  c++  java
  • 51NOD 1149:Pi的递推式——题解

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1149

    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的结果即可。

    不好想啊……以及我曾经打了个表,并且还找到了规律,结果过到29就gg了……

    参考:https://www.cnblogs.com/ivorysi/p/9197222.html

    (这个参考是个神,我这样的凡人能解读到这种地步已经很不容易了)

    总觉得我讲的很有问题啊……那我就顺着这个参考讲吧……

    将递归展开,你就会发现是一张图,而所求即为最上层点到最下层点的方案路径数。

    设$P[i]$表示到$i$这个点减几次pi到达其中一个终点,于是我们到达一次终点所需要经过的整数结点(即-1)与"非整数"结点(即-pi),可以通过设前者为$n-i$,则后者为$P[i]$,路径条数就可以用组合数求出。

    但是要注意的是我们只要到达其中一个目标即会停止,即5-1-pi是合法的,而5-pi-1则是不可能的,即有些pi只能放在最后减,我们需要把这些pi扣除。

    其实并不存在“这些”,事实上显然我们只有一个pi,也就是说下面的关键是判断这个pi是否会导致我们提前结束。

    我们考虑,只要$i$的父亲结点(其实是$i+1$,但叫做父亲节点更好懂些)$P[i+1]>P[i]$,那么我们随便了,提前拐或者不拐最终到达的状态一定一致。

    但是如果不满足的话,则我们在$i+1$或更早处转弯的话,就一定会导致我们提早结束,所以此时我们扣除这个pi即可。

    这是这个参考的做法,个人感觉并不如:https://blog.csdn.net/qq_36797743/article/details/78930126这个更好想一些,但是解法比较自然,顺畅。

    #include<map>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<cctype>
    #include<vector>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef double dl;
    typedef long long ll;
    const dl pi=acos(-1.0);
    const int p=1e9+7;
    const int N=1e6+5;
    inline int qpow(int k,int n){
        int res=1;
        while(n){
            if(n&1)res=(ll)res*k%p;
            k=(ll)k*k%p;n>>=1;
        }
        return res;
    }
    int jc[N],inv[N],P[N];
    void init(int n){
        jc[0]=1;
        for(int i=1;i<=n;i++)jc[i]=(ll)jc[i-1]*i%p;
        inv[n]=qpow(jc[n],p-2);
        for(int i=n-1;i;i--)inv[i]=(ll)inv[i+1]*(i+1)%p;
        inv[0]=1;
    }
    inline int C(int n,int m){
        return (ll)jc[n]*inv[m]%p*inv[n-m]%p;
    }
    int solve(int n){
        if(n<4)return 1;
        for(int i=4;i<=n;i++)P[i]=(dl)(i-4)/pi+1;
        int ans=0;
        for(int i=n;i>=3;i--){
            int s=n-i,t=P[i]-(P[i+1]<=P[i]);
            (ans+=C(s+t,s))%=p;
        }
        return ans;
    }
    int main(){
        int n;
        scanf("%d",&n);
        init(n);
        printf("%d
    ",solve(n));
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    hdu5269 ZYB loves Xor I
    UVA 11181 Probability|Given
    UVA 10277 Boastin' Red Socks
    CodeForces 566B Replicating Processes
    UVA 10714 Ants
    CodeForces 567B Berland National Library hdu-5477 A Sweet Journey
    UVA 10759 Dice Throwing
    UVA 11027
    「CF241E」Flights
    「CF891C」Envy
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/9200909.html
Copyright © 2011-2022 走看看