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的大小影响的 所以要状压这个除法操作. 直接采 ...
随机推荐
- [转帖]PostgreSQL 昨天,今天和明天
PostgreSQL 昨天,今天和明天 http://www.postgres.cn/v2/news/viewone/1/52 原作者:何伟平(laser) 创作时间:2005-01-15 11:44 ...
- 多线程-Task、await/async
Task创建无返回值 Task是.netframwork4.0重新分装的多线程类.原因以前的多线程(thread threadpool)不好用.(.net framwork也是的发展的,现在的EF,刚 ...
- 《Mysql 索引 - 概述》
一:索引的目的 - 索引的出现其实就是为了提高数据查询的效率,就像书的目录一样. 二:InnoDB 索引模型 - InnoDB 采用 B+树 的数据结构进行存储. - 例如,我们建立一张表,分析他的数 ...
- 数据库数据生成Excel表格(多用在导出数据)
最近在项目开发中遇到这样一个需求,用户聊天模块产品要求记录用户聊天信息,但只保存当天的,每天都要刷新清空数据,但聊天记录要以Excel的形式打印出来,于是就引出了将数据库的数据导出成Excel表格的需 ...
- C++ algorithm算法库
C++ algorithm算法库 Xun 标准模板库(STL)中定义了很多的常用算法,这些算法主要定义在<algorithm>中.编程时,只需要在文件中加入#include<algo ...
- Scratch运动模块——有趣的弹球游戏(一)
大家好!我是蓝老师,有了前几期Scratch的基础,相信大家早已摩拳擦掌,跃跃欲试了,甚至还有些小伙伴已经编写了非常不错的程序. 学习编程就是这样不断探索.主动思考.解决问题的过程. 本期内容: 课程 ...
- RDS for MySQL 逻辑备份文件恢复到自建数据库
使用MySQL自带的 mysqldump 工具可以通过逻辑备份文件恢复数据库,本文将介绍详细的逻辑备份恢复数据库操作步骤. 说明 通过物理备份文件恢复到自建数据库请参见RDS for MySQL 物理 ...
- 【转】Visual Studio Code必备插件
先ctrl+shift+p,弹出命令面板-选中Extensions:Install Extensions 或者直接点击左侧栏这个扩展按钮(Ctrl+Shift+X) 然后左侧栏就会显示出很多插件,如图 ...
- 关于MySQL的驱动org.gjt.mm.mysql.Driver
今天看了一个比较老视频使用org.gjt.mm.mysql.Driver来驱动连接,便试了一下看看怎么样,结果一直连不上数据库,后来看了tomcat的后台发现有报这个问题,于是把驱动改成com.mys ...
- 总结一下C++与C#之间的区别
1,C#不支持多重继承 2.在标准的C#安全代码中不支持指针类型的操作,然而,你却能在微软所谓的“非安全代码”中操作指针类型对象. 3.C#中所有对象都只能通过关键词“new”来创建,C++的“类名_ ...