51Nod1149 Pi的递推式

题目

F(x)=1,x[0,4) F ( x ) = 1 , x ∈ [ 0 , 4 )
F(x)=F(x1)+F(xπ),x[4,+) F ( x ) = F ( x − 1 ) + F ( x − π ) , x ∈ [ 4 , + ∞ )
F(n) F ( n ) n106 n ≤ 10 6

题解

假设问题是问每次只加1或2,加到 n n 的方案数。
F(n)=F(n1)+F(n2)
斐波那契?
没错。
O(n) O ( n ) 的另一种方法求,就是求 Σa+2b=nCaa+b Σ a + 2 b = n C a + b a
倒着推不好推?那就顺着推。
那么这道题目就将2替换为 π π ,加到的目标数在区间 (n4,n] ( n − 4 , n ]
假设现在已经加到了 (n4π,n4] ( n − 4 − π , n − 4 ] ,则加 π π 就可以达到目标。
假设现在已经加到了 (n41,n4] ( n − 4 − 1 , n − 4 ] ,则加 1 1 就可以达到目标。
难点难在加到的目标数属于一个区间。
对于第一种情况,枚举加了多少个π,则加的 1 1 的个数也确定了。你会发现除法有余数。这个余数的范围就对应着区间(n41,n4]
对于第二种情况,枚举加了多少个 1 1 ,则加的π的个数也确定了。你会发现除法有余数。这个余数的范围就对应着区间 (n4π,n4] ( n − 4 − π , n − 4 ]
所以就可以愉快地做题了。

心得

从大神们那里得知,问题 F(n)=F(na)+F(nb) F ( n ) = F ( n − a ) + F ( n − b ) 都可以用时间复杂度为 O(n) O ( n ) 的算法求出答案。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 1000010
#define DB double 
#define LL long long
#define mo 1000000007
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fd(i,a,b) for(i=a;i>=b;i--)
using namespace std;
const DB pi=acos(-1);
LL i,j,n,m,ans;
LL jc[N],ny[N];
LL ksm(LL x,LL y){
    LL rs=1;
    for(;y;y>>=1,x=(x*x)%mo)if(y&1)rs=(rs*x)%mo;
    return rs;
}
void pre(){
    LL i;
    jc[0]=jc[1]=ny[0]=ny[1]=1;
    fo(i,2,N-10)jc[i]=(jc[i-1]*i)%mo;
    ny[N-10]=ksm(jc[N-10],mo-2);
    fd(i,N-11,2)ny[i]=(ny[i+1]*(i+1))%mo;
}
LL C(LL n,LL m){return ((jc[n]*ny[m])%mo*ny[n-m])%mo;}
void add(LL &x,LL y){x=x+y>=mo?x+y-mo:x+y;}
int main(){
    scanf("%lld",&n);
    if(n<4){printf("1");return 0;}
    pre();
    fo(i,0,n-4){
        j=(DB)(n-4-i)/pi;
        add(ans,C(i+j,i));
    }
    m=(n-4)/pi;
    fo(i,0,m){
        j=(DB)(n-4-i*pi);
        add(ans,C(i+j,i));
    }
    printf("%lld",ans);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值