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\n",solve(n));
    return 0;
}

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

+本文作者:luyouqi233。               +

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

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

原文地址:https://www.cnblogs.com/luyouqi233/p/9200909.html

时间: 2024-07-30 04:26:25

51NOD 1149:Pi的递推式——题解的相关文章

【51nod】1149 Pi的递推式

题解 我们把这个函数的递归形式画成一张图,会发现答案是到每个出度为0的点的路径的方案数 这个可以用组合数算 记录一下P[i]为i减几次PI减到4以内 如果P[i + 1] > P[i],那么转向的路径走P[i]次,否则走P[i] - 1次 代码 #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <vector> #in

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 数学问

[题解][SHOI2013]超级跳马 动态规划/递推式/矩阵快速幂优化

这道题... 让我见识了纪中的强大 这道题是来纪中第二天(7.2)做的,这么晚写题解是因为 我去学矩阵乘法啦啦啦啦啦对矩阵乘法一窍不通的童鞋戳链接啦 层层递推会TLE,正解矩阵快速幂 首先题意就是给你一个 n 行m 列 的格子图 一只马从棋盘的左上角跳到右下角.每一步它向右跳奇数列,且跳到本行或相邻行. 题意很简单暴力dp的思路也很简单但是数据很恶心虽然远古一点,但毕竟是省选题 1 ≤ n ≤ 50,2 ≤ m ≤ 10^9 不过还是给了我们一点提示:n这么小? 总之我们先找出转移式对于每一个点

hiho 1143 矩阵快速幂 求递推式

题目链接: hihocoder 1143 思路见题目上 快速幂模板: // m^n % k int quickpow(int m,int n,int k) { int b = 1; while (n > 0) { if (n & 1) b = (b*m)%k; n = n >> 1 ; m = (m*m)%k; } return b; } 题解: #include<iostream> #include<cstdio> #include<cstring

递推式转化为矩阵形式

EXAMPLE: 递推式: d(n + 2) = p * d(n + 1) + (1 - p) * d(n); 令G(n) = (d(n + 2), d(n + 1))^T; 则 G(n + 1) = M * G(n); 解得 M = p   1 - p 1    0 G(n) = (M ^ n) * G(0); #

Python的递推式构造列表(List comprehension)

介绍 我们在上一章学习了“Lambda 操作, Filter, Reduce 和 Map”, 但相对于map, filter, reduce 和lamdba, Guido van Rossum更喜欢用递推式构造列表(List comprehension).在这一章我们将会涵盖递推式构造列表(List comprehension)的基础功能. 递推式构造列表(List comprehension)是在Python 2.0中添加进来的.本质上,它是一种数学家用来实现众所周知标记集合的Python方式

一只青蛙从第一级台阶跳到第n级,每次可以跳任意级,共有多少种跳法,并写出递推式

是斐波那契数列问题 假设f(n)是n个台阶跳的次数:(假设已经调到第n个台阶,最后一次是由哪个台阶跳上来的) f(n) = f(n-1)+f(n-2)+...+f(n-(n-1)) + f(n-n) == f(0) + f(1) + f(2) + f(3) + ... + f(n-2) + f(n-1) == f(n) = 2*f(n-1) 所以,可以得出递推式: 1 public static int jumpFloor(int n) { 2 if (n <= 0) 3 return 0; 4

【HDU4990】递推式

题目大意:给定序列 1, 2, 5, 10, 21, 42, 85, 170, 341 …… 求第n项 模 m的结果 递推式 f[i]  = f[i - 2] + 2 ^ (i - 1); 方法一: 构造矩阵, 求递推式 方法二: 直接推公式,递推式求和,得到 f[n] = [2 ^ (n + 1) - 1] / 3 奇数, f[n] = [2 ^ (n + 1) - 2] / 3 偶数: 其实还可以进一步化简, 注意到 2 ^ 2k % 3 = 1, 2 ^ (2k + 1) % 3 = 2,

错排递推式推导

今天听课讲容斥,提到错排,突然发现错排公式什么的好像已经忘了233 努力地回忆了一下,算出前几项,终于还原出了那个递推式↓ f(n)=(n-1)*(f(n-1)+f(n-2)) 根据人赢的教导,只要思(yi)考(yin)下错排的构造就能记住了 然后就认(meng)认(you)真(yi)真(yang)地思(yi)考(yin)了下 用自己的理解把这玩意儿整理了一下↓ 先加一点平时我们说的错排通常是指1~n,f(i)≠i, 其实脑补一下,它也可以看成A,B两个集合,|A|=|B|,对于每一个Ai,都对