[SCOI2010]生成字符串
Posted beretty
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SCOI2010]生成字符串相关的知识,希望对你有一定的参考价值。
题目描述
lxhgww最近接到了一个生成字符串的任务,任务需要他把n个1和m个0组成字符串,但是任务还要求在组成的字符串中,在任意的前k个字符中,1的个数不能少于0的个数。现在lxhgww想要知道满足要求的字符串共有多少个,聪明的程序员们,你们能帮助他吗?
输入输出格式
输入格式:
输入数据是一行,包括2个数字n和m
输出格式:
输出数据是一行,包括1个数字,表示满足要求的字符串数目,这个数可能会很大,只需输出这个数除以20100403的余数
输入输出样例
输入样例#1:
2 2
输出样例#1:
2
说明
limitation
每点2秒
对于30%的数据,保证1<=m<=n<=1000
对于100%的数据,保证1<=m<=n<=1000000
题解
一眼组合数
然后想到像catalan数那样把(0/1)转化到坐标系中
然后就越走越偏==
正解是类似Catalan数的推导公式的东西
选1就是((x,y) -> (x+1,y+1))
选0就是((x,y) -> (x+1,y-1))
所以构成(0/1)字符串的方案数就是(C(n+m,m))
然后有一个条件就是任何时候1的数量都不小于0的数量
所以答案就是从((0,0))出发不碰到(y=-1)的路径
考虑怎么去掉碰到(y=-1)的路径
我们可以把从((0,0))碰到(y=-1)的直线对称下来
就是从((0,-2))走(n+m)步走到((n,n-m))的方案数
所以答案就是走(n+m+1)步1,走(m-1)步0
#include<cstdio>
#include<iostream>
# define int long long
const int M = 2000005 ;
const int mod = 20100403 ;
using namespace std ;
int n , m ;
int Fac[M] , Ans ;
inline int Fpw(int Base , int k) {
int temp = 1 ;
while(k) {
if(k & 1) temp = (temp * Base) % mod ;
Base = (Base * Base) % mod ; k >>= 1 ;
}
return temp ;
}
inline int C(int n , int m)
{ return (Fac[n] * Fpw((Fac[m] * Fac[n - m]) % mod , mod - 2)) % mod ; }
# undef int
int main() {
# define int long long
cin >> n >> m ;
Fac[0] = 1 ; for(int i = 1 ; i <= n + m ; i ++) Fac[i] = (Fac[i - 1] * i) % mod ;
cout << (C(n + m , m) - C(n + m , m - 1) + mod) % mod << endl ;
return 0 ;
}
以上是关于[SCOI2010]生成字符串的主要内容,如果未能解决你的问题,请参考以下文章