AtCoder Beginner Contest 205 E - White and Black Balls(卡特兰数变形)

这篇博客探讨了一种组合计数问题,涉及在坐标轴上从(0,0)出发,通过选择白球和黑球进行移动,最终到达特定点的合法路径数。文章利用了卡特兰数的概念,并给出了当白球和黑球数量已知时,如何计算合法路径数的公式。通过构造对称折线并分析边界条件,博主推导出了非法路径的数量,并通过C(n+m,n)减去非法路径数C(n+m,z)来求得合法路径总数。该问题适用于n≤mn≤mn≤m的情况。
摘要由CSDN通过智能技术生成

LINK

看到题目非常像卡特兰数,实际上就是

考虑以 ( 0 , 0 ) (0,0) (0,0)为起点,选白球相当于往右下走一步,黑球相当于向右上走一步

白球 n n n个,黑球 m m m个,设 x = m − n x=m-n x=mn(先设 m > = n m>=n m>=n)

放在坐标轴上,类似这样的一张图

不管怎么走,最后终点都是 ( n + m , x ) (n+m,x) (n+m,x)

总的方案是 ( n + m n ) \binom{n+m}{n} (nn+m),我们需要知道不合法的方案是多少

容易看出,只要上面的折线越过了 y = − k y=-k y=k这根直线就不合法

我们构造另一条折现,以 y = − k − 1 y=-k-1 y=k1为对称轴翻转得到

发现翻转后折线的终点变为 ( n + m , 2 k + 2 + x ) (n+m,2k+2+x) (n+m,2k+2+x)

也就是不合法的方案数相当于向下走 z z z步,满足 z − ( n + m − z ) = 2 k + 2 + x z-(n+m-z)=2k+2+x z(n+mz)=2k+2+x

于是真正的方案数为 ( n + m n ) − ( n + m z ) \binom{n+m}{n}-\binom{n+m}{z} (nn+m)(zn+m)

n < m n<m n<m时同理

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int mod = 1e9+7;
const int maxn = 2e6+10;
int n,m,k,fac[maxn];
int quick(int x,int n)
{
	int ans = 1;
	for( ; n ; n>>=1,x=x*x%mod )
		if( n&1 )	ans = ans*x%mod;
	return ans;
}
int C(int n,int m)
{
	if( n<m )	return 0ll;
	return fac[n]*quick( fac[m]*fac[n-m]%mod,mod-2 )%mod;
}
signed main()
{
	fac[0] = 1;
	for(int i=1;i<=2000000;i++)	fac[i] = fac[i-1]*i%mod;
	cin >> n >> m >> k;
	if( m+k<n )	puts("0");
	else
	{
		//满足m+k>=n
		int ans = 0;
		if( m>=n )
		{
			int x = m-n;
			int z = (2*k+2+x+n+m)/2;
			ans = C(n+m,m)-C(n+m,z);
		}
		else
		{
			int x = n-m;
			int z = (2*k+2-x+n+m)/2;
			ans = C(n+m,m)-C(n+m,z);	
		}
		cout << ( ans%mod+mod )%mod;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值