889. 满足条件的01序列
给定 n
个 0 和 n 个 1,它们将按照某种顺序排成长度为 2n 的序列,求它们能排列成的所有序列中,能够满足任意前缀序列中 0 的个数都不少于 1
的个数的序列有多少个。
输出的答案对 109+7
取模。
输入格式
共一行,包含整数 n
。
输出格式
共一行,包含一个整数,表示答案。
数据范围
1≤n≤105
输入样例:
3
输出样例:
5
* 假定在一个二维矩阵的地图里,向右走为0,向上走为1,则要求能排列成的所有序列中,
* 能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列,所有点都满足为或者在
* (0,0) 到 (n,n) 的直线上或者在下方。只要有点越过直线 y=x+1 ,再到达点(n,n),
* 则这种排列就是不符合要求的。所以不符合要求的走法一定满足从(0,0) 到 (n-1,n+1) 的
* 路线关于 y=x+1 对称 (因为(0,0) 到 (n,n+1) 的路线一定是不合法的,并且(n,n)与
* (n-1,n+1) 关于 y=x+1 对称。)。那么我们只要 C(2*n,n) - C(2*n,n-1) 就是答案。
*
* C(2*n,n) - C(2*n,n-1) =C(2*n,n)/(n+1);()
*
* 卡特兰数:
* C(2*n,n) - C(2*n,n-1) =(2*n)! / (n! * n! * (n+1))
- /**
- * 假定在一个二维矩阵的地图里,向右走为0,向上走为1,则要求能排列成的所有序列中,
- * 能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列,所有点都满足为或者在
- * (0,0) 到 (n,n) 的直线上或者在下方。只要有点越过直线 y=x+1 ,再到达点(n,n),
- * 则这种排列就是不符合要求的。所以不符合要求的走法一定满足从(0,0) 到 (n-1,n+1) 的
- * 路线关于 y=x+1 对称 (因为(0,0) 到 (n,n+1) 的路线一定是不合法的,并且(n,n)与
- * (n-1,n+1) 关于 y=x+1 对称。)。那么我们只要 C(2*n,n) - C(2*n,n-1) 就是答案。
- *
- * C(2*n,n) - C(2*n,n-1) =C(2*n,n)/(n+1);()
- *
- * 卡特兰数:
- * C(2*n,n) - C(2*n,n-1) =(2*n)! / (n! * n! * (n+1))
- */
-
- #include
-
- using namespace std;
-
- typedef long long LL;
-
- const int mod=1e9+7,maxn=1e5+10;
- int fac[2*maxn],infac[maxn];
-
- int qmi(int a,int b,int p)
- {
- int res=1;
- while(b)
- {
- if(b&1)
- res=(LL)res*a%mod;
- a=(LL)a*a%mod;
- b>>=1;
- }
-
- return res;
- }
-
- void init(int n)
- {
- fac[0] = infac[0] = 1; //初始化
- for(int i=1;i<=2*n;++i)
- fac[i]=(LL)fac[i-1]*i%mod;
-
- for(int i=1;i<=n;++i)
- infac[i]=(LL)infac[i-1]*qmi(i,mod-2,mod)%mod; //必须要用qmi求逆元
- }
-
-
- int main()
- {
- int n;
- cin >> n;
- init(n);
- cout << (LL)fac[2*n]*infac[n]%mod*infac[n]%mod *qmi(n+1,mod-2,mod)%mod << endl;
- return 0;
- }
130. 火车进出栈问题
一列火车 n
节车厢,依次编号为 1,2,3,…,n
。
每节车厢有两种运动方式,进栈与出栈,问 n
节车厢出栈的可能排列方式有多少种。
输入格式
输入一个整数 n
,代表火车的车厢数。
输出格式
输出一个整数 s
表示 n
节车厢出栈的可能排列方式数量。
数据范围
1≤n≤60000
输入样例:
3
输出样例:
5
* 卡特兰数:
* C(2*n,n) - C(2*n,n-1) =(2*n)! / (n! * n! * (n+1));
*
* 这个题与满足条件的01序列解法一样,只不过这个题是输出全部方案数,不取模,
* 输出高精度数据;由于数据较大,所以我们用质因数分解的方法来求解。
* 最后由于高精度数据相乘是主要的算法时间消耗,因此我们优化高精度数据相乘,
* 用LL来存储结果,每次相乘我们以 M=1e9 作为进制数,(这样两个M相乘也不会爆LL);
* 这样能减少许多乘法步骤;这种方法称为高精度压位。
- /**
- * 假定在一个二维矩阵的地图里,向右走为0,向上走为1,则要求能排列成的所有序列中,
- * 能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列,所有点都满足为或者在
- * (0,0) 到 (n,n) 的直线上或者在下方。只要有点越过直线 y=x+1 ,再到达点(n,n),
- * 则这种排列就是不符合要求的。所以不符合要求的走法一定满足从(0,0) 到 (n-1,n+1) 的
- * 路线关于 y=x+1 对称 (因为(0,0) 到 (n,n+1) 的路线一定是不合法的,并且(n,n)与
- * (n-1,n+1) 关于 y=x+1 对称。)。那么我们只要 C(2*n,n) - C(2*n,n-1) 就是答案。
- *
- * C(2*n,n) - C(2*n,n-1) =C(2*n,n)/(n+1);()
- *
- * 卡特兰数:
- * C(2*n,n) - C(2*n,n-1) =(2*n)! / (n! * n! * (n+1));
- *
- * 这个题与满足条件的01序列解法一样,只不过这个题是输出全部方案数,不取模,
- * 输出高精度数据;由于数据较大,所以我们用质因数分解的方法来求解。
- * 最后由于高精度数据相乘是主要的算法时间消耗,因此我们优化高精度数据相乘,
- * 用LL来存储结果,每次相乘我们以 M=1e9 作为进制数,(这样两个M相乘也不会爆LL);
- * 这样能减少许多乘法步骤;这种方法称为高精度压位。
- */
-
-
- #include
- #include
-
- using namespace std;
-
- typedef long long LL;
-
- const LL M=1e9;
- const int N = 12e4+10;
- int p[N],sum[N],num=0;
- bool hs[N];
-
- void get_primer(int n) //获得n以内的素数
- {
- for(int i=2;i<=n;++i)
- {
- if(hs[i]==0)
- p[num++]=i;
- for(int j=0;p[j]<=n/i;++j)
- {
- hs[p[j]*i]=1;
- if(i%p[j]==0)
- break;
- }
- }
- }
-
- int cal(int n,int p) //计算n! 内有多少个因子p
- {
- int cnt=0;
- while (n)
- {
- cnt+=n/p;
- n/=p;
- }
-
- return cnt;
- }
-
- void get_pow(int a,int b) //将C(a,b) 进行质因子分解
- {
- for(int i=0;i
- {
- int cnt=cal(a,p[i]) -cal(b,p[i])*2;
- sum[i]=cnt;
- }
- }
-
- void mul(vector
&A,int b) //高精度与整数相乘 - {
- LL d=0;
- for(int i=0;i
size();++i) - {
- d+=A[i]*b;
- A[i]=d%M;
- d/=M;
- }
-
- while(d)
- {
- A.push_back(d%M);
- d/=M;
- }
- }
-
- void print(vector
&res) //输出高精度数据 - {
- cout << res.back(); // 最后一位不需要输出九位
- for(int i=res.size()-2;i>=0;--i)
- printf("%09lld",res[i]); //因为是按着1e9作为进制数,所以中间的位要输出九位,
- cout << endl; //不足九位的补零
- }
-
- int main()
- {
- int n;
- cin >> n;
- get_primer(2*n);
- get_pow(2*n,n);
-
- int r=n+1;
- for(int i=0;i
1;++i) - {
- while(r%p[i]==0)
- {
- sum[i]-=1;
- r/=p[i];
- }
- }
-
- vector
res; - res.push_back(1);
-
- for(int i=0;i
- for(int j=0;j
- mul(res,p[i]);
-
- print(res);
- return 0;
-
- }
-
相关阅读:
【Java网络原理】 四
从源码看std::weak_ptr
postgresql源码学习(51)—— 提交日志CLOG 提交日志CLOG 原理 用途 管理函数
模型的选择与调优(网格搜索与交叉验证)
跟艾文学编程《Python基础》(6)numpy数值计算
Django使用Token认证(simplejwt库的配置)
河南共享股东系统开发模式介绍
场景应用:你知道 i = i++;的含义么?
草图大师SketchUp Pro 2023 for Mac
数字化开采|AIRIOT智慧矿山自动化生产解决方案
-
原文地址:https://blog.csdn.net/qq_51825761/article/details/126324971