51NOD 1149:Pi的递推式——题解
Posted luyouqi233
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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://blog.csdn.net/qq_36797743/article/details/78930126
为了方便理解,我们可以把题意变成:有个数,初值为0,每次可以$+1/+pi$,求有多少种方法使得该数$(x-4,x]$。
那就……也不好办啊。如果我们设达到目标状态需要+1次数为$s$,+pi次数为$t$,那么显然答案贡献为$C(s+t,t)$。
只是s和t的值不好求。其实,我们可以划一个界限值i,这样$s=x-i$,t就表示到达$(i-4,i]$所需要的+pi次数了。
$P[i]=(i-4)/pi+1$就求出来了。
但是我们求的是到达$(x-4,x]$即停止,有时我们不需要那么多pi,所以需要减掉。
#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/+
+++++++++++++++++++++++++++++++++++++++++++
以上是关于51NOD 1149:Pi的递推式——题解的主要内容,如果未能解决你的问题,请参考以下文章