Description
设定义域为非负实数的函数F
F(x)=1,0≤x<4
F
(
x
)
=
1
,
0
≤
x
<
4
F(x)=F(x−1)+F(x−π),x≥4
F
(
x
)
=
F
(
x
−
1
)
+
F
(
x
−
π
)
,
x
≥
4
其中
π
π
为圆周率,
π=3.1415926...
π
=
3.1415926...
给出N,求
F(N)
F
(
N
)
答案对
109+7
10
9
+
7
取模
N≤106 N ≤ 10 6
Solution
这是类似斐波那契数列的递推式
考虑斐波那契数列的组合意义,一条长度为N的路,一次可以走1的距离或者走2的距离,求方案数
同理,现在一次可以走1的距离或者走 π π 的距离,你可以从 [0,4) [ 0 , 4 ) 的任意一个点出发,(并且第一步必须走出这个区间),求走到N的方案数
枚举走了多少次
π
π
,然后根据第一步是走1还是走pi讨论一下,用组合数计算即可
具体可以看代码
Code
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cstring>
#define fo(i,a,b) for(int i=a;i<=b;++i)
#define fod(i,a,b) for(int i=a;i>=b;--i)
#define N 1000005
#define mo 1000000007
#define LL long long
using namespace std;
int n;
const double pi=acos(-1);
LL js[N],ny[N];
LL C(int n,int m)
{
if(n<m) return 0;
return js[n]*ny[m]%mo*ny[n-m]%mo;
}
int main()
{
cin>>n;
if(n<4) printf("1\n");
else
{
js[0]=ny[0]=js[1]=ny[1]=1;
fo(i,2,n)
{
js[i]=js[i-1]*(LL)i%mo;
ny[i]=(-ny[mo%i]*(mo/i)%mo+mo)%mo;
}
fo(i,2,n) ny[i]=ny[i-1]*ny[i]%mo;
int l=n/pi;
LL ans=0;
fo(i,0,l)
{
if(n-4-(i-1)*pi<0) break;
int c=n-i*pi-3;
if(c>0) ans=(ans+C(c+i-1,c-1))%mo;
if(i>0)
{
int x=n-3-i*pi,y=n-4-(i-1)*pi;
fo(j,max(0,x),y) ans=(ans+C(j+i-1,i-1))%mo;
}
}
printf("%lld\n",ans);
}
}