51nod 1843 排列合并机(DP+组合)
不过求ggg不用O(n2)DPO(n^2)DPO(n2)DP,g[n]g[n]g[n]直接就是卡特兰数的第n−1n-1n−1项。即:
g[n]=(2(n−1)n−1)−(2(n−1)n−2)g[n]=\binom{2(n-1)}{n-1}-\binom{2(n-1)}{n-2}g[n]=(n−12(n−1))−(n−22(n−1))
相当于在平面直角坐标系中,要从(0,0)(0,0)(0,0)走到(n,n)(n,n)(n,n),有一条线段y=x(x∈(0,n))y=x(x\in(0,n))y=x(x∈(0,n))不能触碰,注意是开区间。所以卡特兰数/组合数的计算方法就行了。
CODE
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 105;
int n, mod, g[MAXN], f[MAXN][MAXN][MAXN], fac[MAXN<<1], inv[MAXN<<1];
int C(int n, int m) { return m > n ? 0 : 1ll * fac[n] * inv[m] % mod * inv[n-m] % mod; }
int main(){
scanf("%d%d", &n, &mod);
fac[0] = inv[0] = inv[1] = fac[1] = 1;
for(int i = 2; i <= (n<<1); ++i){
fac[i] = 1ll * fac[i-1] * i %mod;
inv[i] = 1ll * (mod - mod/i) * inv[mod%i] % mod;
}
for(int i = 2; i <= (n<<1); ++i) inv[i] = 1ll * inv[i-1] * inv[i] % mod;
for(int i = 1; i <= n; ++i) g[i] = C(2*i - 2, i - 1) - C(2*i - 2, i - 2);
f[0][0][0] = 1;
for(int i = 0; i <= n; ++i)
for(int j = 0; j <= n; ++j) if(i || j) {
for(int k = max(0, i+j-n); k <= i && k <= j; ++k){
int &ret = f[i][j][k];
if(i && k) ret = (ret + 1ll * f[i-1][j][k-1] * (j-k+1)) % mod;
if(j && k) ret = (ret + 1ll * f[i][j-1][k-1] * (i-k+1)) % mod;
if(i) ret = (ret + 1ll * f[i-1][j][k] * (n - (i-1+j-k))) % mod;
if(j) ret = (ret + 1ll * f[i][j-1][k] * (n - (i+j-1-k))) % mod;
for(int d = 1; d <= k; ++d)
ret = (ret - 1ll * f[i-d][j-d][k-d] * C(n-(i+j-k-d), d) % mod * g[d] % mod * fac[d] % mod) % mod;
}
}
printf("%d\n", (f[n][n][n] + mod) % mod);
}
没做过这种类型的感觉好难。。
51nod 1843 排列合并机(DP+组合)的更多相关文章
- BZOJ4517 Sdoi2016 排列计数 【DP+组合计数】*
BZOJ4517 Sdoi2016 排列计数 Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 ...
- 51nod 1250 排列与交换——dp
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 仔细思考dp. 第一问,考虑已知 i-1 个数有多少种方案. ...
- 51Nod 1250 排列与交换 —— DP
题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1250 看了半天... 把第一问想成逆序对的话似乎很容易想了,新加入 ...
- 51Nod 1268 和为K的组合
51Nod 1268 和为K的组合 1268 和为K的组合 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 给出N个正整数组成的数组A,求能否从中选出若干个,使 ...
- hdu 4945 2048 (dp+组合的数目)
2048 Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submi ...
- 【BZOJ】2111: [ZJOI2010]Perm 排列计数 计数DP+排列组合+lucas
[题目]BZOJ 2111 [题意]求有多少1~n的排列,满足\(A_i>A_{\frac{i}{2}}\),输出对p取模的结果.\(n \leq 10^6,p \leq 10^9\),p是素数 ...
- 51nod 1020 逆序排列 递推DP
1020 逆序排列 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么 ...
- 51Nod 1021 石子合并 Label:Water DP
N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有 ...
- 3.29省选模拟赛 除法与取模 dp+组合计数
LINK:除法与取模 鬼题.不过50分很好写.考虑不带除法的时候 其实是一个dp的组合计数. 考虑带除法的时候需要状压一下除法操作. 因为除法操作是不受x的大小影响的 所以要状压这个除法操作. 直接采 ...
随机推荐
- [转帖]为何 CPU 只用硅,而不用能耗更低的锗制作?知乎好文章
作者:鲁超链接:https://www.zhihu.com/question/28935966/answer/617701106来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...
- ubuntu中不能使用终端的情况
跟着网上的步骤去升级了一波python3,可谓一波未平! 当我将ubuntu中自带的python3.5升级3.6时,突然发现一个问题,怎么终端打不开了,于是去百度,找到一个博主的笔记,和我的情况一模一 ...
- Android 卸载应用程序
最近工作中接触Android应用实现卸载自身的逻辑,踩了一些坑之后整理下来.使用的方法是Intent.ACTION_DELETE,这里没有什么好说的. MainActivity.java : pack ...
- 为什么用JS取不到cookie的值?解决方法如下!
注意:cookie是基于域名来储存的.要放到测试服务器上或者本地localhost服务器上才会生效.cookie具有不同域名下储存不可共享的特性.单纯的本地一个html页面打开是无效的. 明明在浏览中 ...
- 21-MySQL DBA笔记-高可用性
第21章 高可用性 本章将为读者介绍单点故障的处理策略,以及单点故障最为主流的解决方案:MySQL数据库切换. 21.1 概述 可用性定义为系统保持正常运行时间的百分比,高可用可以理解为系统可用时间的 ...
- java 框架-模板引擎FreeMarker
https://www.cnblogs.com/itdragon/p/7750903.html FreeMarker是一个很值得去学习的模版引擎.它是基于模板文件生成其他文本的通用工具.本章内容通过如 ...
- Go 代码风格和规范
Go 语言写起来类似于C语言,因此熟悉C语言及其派生语言(C++.C#.Objective-C 等)的人都会迅速熟悉这门语言 编码风格 标识符命名规范 在习惯上,Go语言程序员推荐使用驼峰式命名,当名 ...
- 基于【 centos7】五 || GitLab环境搭建
一.基于Docker部署GitLab环境搭建 1.下载镜像 docker pull beginor/gitlab-ce:11.0.1-ce.0 2.创建GitLab 的配置 (etc) . 日志 (l ...
- oracle学习笔记:update一整列 关联更新
普通的 update 都是根据条件来对部分列的内容进行修改,用法如下: update temp_cwh_table set name = 'xxx' where id = 1; 假设现在有2张表:A. ...
- pymsql及事务
MySQL知识点补充 1.去重 distinct select distinct name,age from t1; # 针对查找出来的结果整行(记录)进行去重,也就是相同行只保存一个 注意点:dis ...