ZCMU - 2157: K.ly的旅行计划

简介: ZCMU - 2157: K.ly的旅行计划

题目链接:点击打开链接

题目大意:初始点为0,目标点为m(可能是负数),对于一步有:1/4的概率-1,1/4的概率+1,1/2的概率不变,求走n步,从0到m的概率是多少,假设答案为a/b,以a*b的乘法逆元形式输出。


解题思路:

设x,y,z分别为+1的步数,-1的步数,0的步数;则:


x*1+y*(-1)+z*0 = x-y = m

x+y+z = n

==>

x=m+y

z=n-m-y-y


假设到达目标点包含以下操作(m+i)步+1(向右),(i)步-1(向左),(n-m-i-i)步0(不变)。(i-->从 0 到 m+i+i<=n)


于是可得:

(1)分母部分为:pow(2,n-m-i-i)*pow(4,m+i+i)。

(2)分子部分为(分子部分是一个组合数):C(n,m+i)*C(n-m-i,i),因为总共包含三种操作固定两种自然确定最后一种,这个表达式是确定了+1的组合情况和-1的组合情况。


最后,不断求解累加即是答案。因为题目涉及一些乘分母,阶乘,组合数等东西,所以需要一些预处理,以及乘法逆元化。


AC 代码

#include<bits/stdc++.h>
#include<cmath>
#define mem(a,b) memset(a,b,sizeof a)
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=100000+10;
// 快速模幂(配合:费马小定理)
ll qpow(ll a,ll b)
{
    ll ans=1; a=a%mod;
    while(b)
    {
        if(b&1) ans=ans*a%mod;
        b>>=1;
        a=a*a%mod;
    }
    return ans;
}
// 扩展欧几里德
void extgcd(ll a,ll b,ll& d,ll& x,ll& y){
    if(!b){ d=a; x=1; y=0;}
    else{ extgcd(b,a%b,d,y,x); y-=x*(a/b); }
}
ll inverse(ll a,ll n){
    ll d,x,y;
    extgcd(a,n,d,x,y);
    return d==1?(x+n)%n:-1;
}
ll a1[maxn],b1[maxn],c1[maxn]; // 1/4 1/2 i!
ll a2[maxn],b2[maxn],c2[maxn]; // 同上对应的逆元数组
int main()
{
    a1[0]=a2[0]=b1[0]=b2[0]=c1[0]=c2[0]=1;
    for(int i=1;i<=100000;i++)
    {
        a1[i]=(a1[i-1]*4)%mod;
        b1[i]=(b1[i-1]*2)%mod;
        c1[i]=(c1[i-1]*i)%mod;
        // 费马小定理+快速幂(O(log2N))(mod 为素数 + mod较大时推荐):用 b^(M-2) 代替 1/b
        a2[i]=qpow(a1[i],mod-2);
        b2[i]=qpow(b1[i],mod-2);
        c2[i]=qpow(c1[i],mod-2);
        // 扩展欧几里德(O(lnN))(GCD是否为1,1存在逆元,非1不存在逆元)
//        a2[i]=inverse(a1[i],mod);
//        b2[i]=inverse(b1[i],mod);
//        c2[i]=inverse(c1[i],mod);
    }
    int T; scanf("%d",&T);
    ll n,m;
    while(T-- && ~scanf("%lld%lld",&n,&m))
    {
        if(m<0) m=-m; // m,-m 结果等价
        ll rs=0,ans=0;
        // C(n-m-i,i) * C(n,m+i) ==> (n-m-i)!/(i!*(n-m-i-i)!) * n!/((m+i)!*(n-m-i)!) ==> n!/(i!*(n-m-i-i)!*(m+i)!)
        for(int i=0;m+i+i<=n;i++)
            rs=(rs+c1[n]*c2[m+i]%mod*c2[i]%mod*c2[n-m-i-i]%mod*a2[m+i+i]%mod*b2[n-m-i-i]%mod)%mod;
        printf("%lld\n",rs);
    }
    return 0;
}


目录
相关文章
|
7月前
|
算法 数据挖掘
Sentieon | 每周文献-Population Sequencing-第三十四期
Sentieon | 每周文献-Population Sequencing-第三十四期
50 0
|
4月前
|
机器学习/深度学习 数据可视化 算法
2023年美赛C题 预测Wordle结果Predicting Wordle Results这题太简单了吧
本文提供了2023年美赛C题"预测Wordle结果"的详细建模方案、Python代码实现、数据和图片,包括对Wordle游戏规则的理解、数据分析、模型构建和结果预测,以及如何撰写给《纽约时报》字谜编辑的信件。
56 1
2023年美赛C题 预测Wordle结果Predicting Wordle Results这题太简单了吧
|
6月前
|
传感器 存储 供应链
plant simulation物流系统仿真案例
plant simulation物流系统仿真案例
120 0
|
7月前
|
数据挖掘 数据库
数据分享|MATLAB、R基于Copula方法和k-means聚类的股票选择研究上证A股数据
数据分享|MATLAB、R基于Copula方法和k-means聚类的股票选择研究上证A股数据
|
7月前
|
人工智能 Go
【2024美赛】E题(中英文):房产保险的可持续性Problem E: Sustainability of Property Insurance
【2024美赛】E题(中英文):房产保险的可持续性Problem E: Sustainability of Property Insurance
78 1
|
传感器 机器学习/深度学习 算法
基于simulink实现无人机导航系统
基于simulink实现无人机导航系统
|
算法 决策智能
【算法进阶】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题
若干个城市,任何两个城市之间的距离都是确定的,现要求一旅行商从某城市出发必须经过每一个城市且只在一个城市逗留一次,最后回到出发的城市,问如何事先确定一条最短的线路已保证其旅行的费用最少?
422 0
【算法进阶】用模拟退火(SA, Simulated Annealing)算法解决旅行商问题
ZCMU - 1951: ly和wjw的无聊游戏
ZCMU - 1951: ly和wjw的无聊游戏
122 0
|
Perl
植物的Transcription Factor挖掘笔记
1、了解一下有哪些转录因子 1、在网站http://planttfdb.cbi.pku.edu.cn/中查找已知转录因子有哪些 2、下载已有种子 根据第一步中已知的转录因子的简写,在http://pfam.xfam.org/search#searchKeywordBlock中检索相应的种子文件,如果有,则下载,若没有则下一步自己制作。
1197 0