• 卡特兰数 洛谷P1641 [SCOI2010]生成字符串


    卡特兰数

    参考博客

    介绍

    卡特兰数为组合数学中的一种特殊数列,用于解决一类特殊问题

    (f(n))为卡特兰数的第n项

    其通项公式为

    [f(n)=frac{2nchoose n}{n+1} ]

    关于它的证明

    当然也有递推式

    [f(n)=sumlimits_{i=0}^{n-1}f(i)ast f(n-i-1) ]

    最常用的则是对于通项的变形式

    [f(n)={2nchoose n}-{2nchoose n-1} ]

    在此给出一较易的证明

    例题

    我们来看一道例题洛谷 p1641 生成字符串

    比较模板的一道卡特兰数的例题,用上面给出的公式可以直接求解,我们对本题建模,假设m=n,我们建立一个

    (n*n)的网格图,把0看作向上走一个单位,把1看作向右走一个单位,我们以((0,0))为起点,((n,n))为终点,

    考虑到本题的限制,即在任意的前 k 个字符中,1 的个数不能少于 0 的个数,所以,每一个合法的路

    径都不能越过该网格图的对角线,设直线(l)为将对角线向上平移一个单位所得到的直线,所有经过

    (l)的路径都是非法路径,我们用所有路径数减去非法路径数就是合法的路径数,设(x)为一非法路径与

    直线(l)的交点,对该路径(x)后的部分以(l)为对称轴对称过去,我们发现,所有非法路径对称后的

    终点都为((n-1,n+1))因为所有的对称后路径与先前的非法路径都是一一对应的,所以,非法路径个数

    就是对称后路径个数,所以,用所有路径减去非法路径就是合法路径个

    数,其实答案就是上面第三个公式。

    对于(m<=n),同样的思路,只不过非法路径的终点与(m=n)不一样了,只需

    要求出对称点,其余与上相同

    如果不是很清楚,建议看一下第三个公式的证明的博客

    代码

    具体求组合数采用卢卡斯定理

    注意,在遇到需要取模后输出的题目,算出的答案可能为负数,所以就需要+mod后%mod,本题如果不这样写的话只有70分
    .

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #define int long long
    using namespace std;
    const int maxn=3e6+10;
    const int p=20100403;
    int n,m;
    int a[maxn];
    int power(int x,int t)
    {
        if(x==0) return 0;
    	x%=p;
        int b=1;
        while(t)
        {
            if(t&1) b=b*x%p;
            x=x*x%p; t>>=1;
        }
        return b;
    }
    int cm(int a1,int b1){
    	if(a1<b1)
    		return 0;
    	return (a[a1]*power(a[b1],p-2)%p)*power(a[a1-b1],p-2)%p;
    }
    int lucas(int n,int m,int p){
    	if(!m){
    		return 1;
    	}
    	return cm(n%p,m%p)*lucas(n/p,m/p,p)%p;
    }
    signed main(){
    	ios::sync_with_stdio(false);
    	cin>>n>>m;
    	a[0]=1;
    	for(int i=1;i<=n+m+10;i++){
    		a[i]=(a[i-1]*i)%p; 
    	}
    	int nn=m-1;
    	int mm=n-nn+m;//(nn,mm)为非法路径的终点
    	cout<<(lucas(n+m,n,p)-lucas(nn+mm,nn,p)+p)%p;
    	return 0;
    }
    
  • 相关阅读:
    Struts2 拦截器(interceptor) 与 模型驱动3中传值方式
    Struts2 OGNL表达式
    ThreadLocal 是什么
    struts2的值栈(重点) 值栈是一个存储数据的内存结构 本质是一个接口 它的实现类OgnlValueStack
    Struts2 普通的java类 (Action)与Servlet通信 主要对象那个ServletActionContext 与 ActionContext对象来获取servlet中request对象和response对象
    struts2是多例的
    Django中一个项目里怎么使用两个数据库
    MYSQL中的锁
    详解Linux中文乱码问题终极解决方法
    Docker-compose up时报错:
  • 原文地址:https://www.cnblogs.com/rpup/p/13974898.html
Copyright © 2020-2023  润新知