Acwing---889. 满足条件的01序列(Java)_数学知识_组合计数_卡特兰数

原题链接

①. 题目

在这里插入图片描述

②. 思路

在这里插入图片描述
在这里插入图片描述

  • 直接将问题转化为走格子,若 0 表示向右走,1 表示向上走,那么任何前缀中 0 的个数不少于 1 的个数就转化为,路径上的任意一点,横坐标大于等于纵坐标。所有前缀中0的个数大于1的个数都在红线以下,把经过红线的路径进行对称,那么他们的终点都会被映射到(n−1,n+1),只要计算终点是(n−1,n+1)的路径有多少个,再用总数减去就是最终的答案。

  • 表示从 (0,0) 走到 (n,n) 的路径,在绿线及以下表示合法,若触碰红线即不合法。
    在这里插入图片描述

  • 算法核心:每一条从(0,0)走到(n,n)的非法路径都对应一条从(0,0)走到(n-1,n+1)的非法路径

  • 直接推出公式 Cn2n−Cn−12n ,化简得 Cn2n/(n+1)
    在这里插入图片描述

③. 学习点

组合计数_卡特兰数

④. 代码实现

import java.util.Scanner;

public class Main {
    
    
	static int m=(int)1e9+7;
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n=sc.nextInt();
		long res=1;
		//直接套用推出来的公式
		for (int i = 1,j=2*n; i <=n; i++,j--) {
    
    
			res=res*j%m; //求2n*(2n-1)*(2n-2)*...*(2n-n+1)
			res=res*qmi(i,m-2,m)%m; //快速幂求n的阶乘的逆元
		}
		System.out.println(res*qmi(n+1,m-2,m)%m); //最后乘上n+1的逆元
	}
	
	//快速幂求 a^k%m
	static long qmi(long a,long k,long m) {
    
    
		long res=1;
		while(k!=0) {
    
    
			if((k&1)==1) res=res*a%m;
			a=a*a%m;
			k>>=1;
		}
		return res;
	}	
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45480785/article/details/114104388