【题解】有限制的排列 [51nod1296]
【题解】有限制的排列 [51nod1296]
【题目描述】
给出 \(n,m_1,m_2\) 和 \(\{a[1],a[2]...a[m_1]\},\{b[1],b[2]...b[m_2]\}\)
计算整数 \([1,n]\) 满足以下条件的排列个数:
位置 \(a[i]\) \((i \in [1,m_1])\) 上的数均小于其邻居,位置 \(b[i]\) \((i \in [1,m_2])\) 上的数均大于其邻居(位置编号从 \(0\) 开始)。
答案对 \(1e9+7\) 取模。
如样例:
\(N=4,a=\{1\},b=\{2\}\),符合条件的排列有:
\(2,1,4,3\)
\(3,2,4,1\)
\(4,2,3,1\)
\(3,1,4,2\)
\(4,1,3,2\)
答案为 \(5\) 。
【样例】
样例输入:
4 1 1
1
2
样例输出:
5
【数据范围】
\(100\%\) \(1 \leqslant n \leqslant 5000,\) \(1 \leqslant m_1,m_2 \leqslant n\)
【分析】
一道 \(dp\) 题,要维护的关键信息在于相邻数字的大小关系,用 \(dp[i][j]\) 表示整数 \([1,i]\) 满足要求的排列中,最后一个数选 \(a[i]=j\) 的排列数量。
为了方便状态的转移,只记录每个数和前一个数相比需要满足的大小关系。
开一个数组 \(p\):
\(p[i]=0\) : \(a[i]\) 无限制,\(dp[i][j]=\sum_{k=1}^{i-1} dp[i-1][k]\)
\(p[i]=1\) : \(a[i]\) 要小于 \(a[i-1]\),\(dp[i][j]=\sum_{k=j}^{i-1} dp[i-1][k]\)
\(p[i]=2\) : \(a[i]\) 要大于 \(a[i-1]\),\(dp[i][j]=\sum_{k=1}^{j-1} dp[i-1][k]\)
通常的理解是直接在已选好的序列后面加入了一个 \(j\),但并不能保证 \(j\) 在前面一定没有出现过,所以要理解为:把前面已选好的序列中大于等于 \(j\) 的数都加一后再把 \(j\) 加到后面。
所以当 \(p[i]=1\) 时,\(k\) 的下边界是 \(j\) 而不是 \(j+1\)(单纯的理解为结尾比 \(j\) 大的情况),因为当 \(a[i-1]\) 为 \(j\) 时,加了 \(1\) 之后就大于 \(j\) 了,此时 \(a[i]\) 恰好可为 \(j\) 。
而当 \(p[i]=2\) 时,\(k\) 的上边界却不能取到 \(j\),如果取到了 \(j\),那么 \(j+1\) 就会大于 \(j\),即 \(a[i-1] > a[i]\),该种排列与限制关系矛盾。
求和的过程可以用前缀和省略掉,初始化为 \(dp[1][1]=S[1]\) (\(dp[1]=1\) 为的是防止出现 \(n=1\) 这样的奇葩数据)。
时间复杂度:\(O(n^2)\) 。
【Code】
#include<algorithm>
#include<cstdio>
#include<queue>
#define Re register int
const int N=5003,P=1e9+7;
int x,n,m1,m2,ans,p[N],S[N],dp[N][N];
//p[i]=0 无限制
//p[i]=1 a[i-1]>a[i]
//p[i]=2 a[i-1]<a[i]
inline void in(Re &x){
int f=0;x=0;char c=getchar();
while(c<'0'||c>'9')f|=c=='-',c=getchar();
while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
int main(){
in(n),in(m1),in(m2);
while(m1--)in(x),++x,p[x]=1,p[x+1]=2;
while(m2--)in(x),++x,p[x]=2,p[x+1]=1;
dp[1][1]=S[1]=1;
for(Re i=2;i<=n;++i){
for(Re j=1;j<=i;++j){
if(!p[i])(dp[i][j]+=S[i-1])%=P;
else if(p[i]<2)(dp[i][j]+=(S[i-1]-S[j-1]+P)%P)%=P;
else (dp[i][j]+=S[j-1])%=P;
}
for(Re j=1;j<=i;++j)S[j]=(S[j-1]+dp[i][j])%P;
}
for(Re i=1;i<=n;++i)(ans+=dp[n][i])%=P;
printf("%d",ans);
}
【题解】有限制的排列 [51nod1296]的更多相关文章
- 【题解】逆序排列 [51nod1020]
[题解]逆序排列 [51nod1020] 传送门:逆序排列 \([51nod1020]\) [题目描述] 共 \(T\) 组测试点,每一组给出 \(2\) 个整数 \(n\) 和 \(k\),在 \( ...
- 题解 P4071 【[SDOI2016]排列计数】 (费马小定理求组合数 + 错排问题)
luogu题目传送门! luogu博客通道! 这题要用到错排,先理解一下什么是错排: 问题:有一个数集A,里面有n个元素 a[i].求,如果将其打乱,有多少种方法使得所有第原来的i个数a[i]不在原来 ...
- hdu 5727 二分图+环排列
Necklace Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Su ...
- BZOJ 一句话题解
菜鸡刷题记录 [题号:题解] 1008:简单排列组合 #include <bits/stdc++.h> using namespace std; #define ll long long ...
- AtCoder Grand Contest 055题解
我太菜啦!!!md,第一题就把我卡死了...感觉对构造题不会再爱了... A - ABC Identity 先来看这个题吧,题意就是给定你一个字符串,让你将这个字符串最多分成6个子串,使得每个字符都在 ...
- BZOJ1653: [Usaco2006 Feb]Backward Digit Sums
1653: [Usaco2006 Feb]Backward Digit Sums Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 207 Solved: ...
- ZOJ Monthly, March 2013
A题 题目大意:给出一棵树,一开始节点值均为0,先要求完成在线操作:将某子树所有节点值取反,或者查询某子树总点权. 题解:很基础的线段树题,既然两个操作都是子树操作,那么就先树链剖分一下,将子树操作转 ...
- CODEFORCES 25E Test
题意 三个字符串,找一个字符串(它的子串含有以上三个字符串)使它的长度最短,输出此字符串的长度. 题解 先枚举字符串排列,直接KMP两两匹配,拼接即可...答案取最小值.. 常数巨大的丑陋代码 # i ...
- Codeforces Round #209 (Div. 2)A贪心 B思路 C思路+快速幂
A. Table time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
随机推荐
- bugku insertsql
题目链接 0X00题目给出的PHP代码 error_reporting(0); function getIp(){ $ip = ''; if(isset($_SERVER['HTTP_X_FORWAR ...
- maven 学习---Maven安装配置
想要安装 Apache Maven 在Windows 系统上, 只需要下载 Maven 的 zip 文件,并将其解压到你想安装的目录,并配置 Windows 环境变量. 所需工具 : JDK 1.8 ...
- error: undefined reference to `vtable for
出现如下错误: 解决办法 当类中加入Q_OBJECT,需要手动删除中间文件,再构建
- 高性能的编程IO与NIO阻塞分析
1.什么是阻塞,什么是非阻塞? 阻塞:结果返回之前,线程一直被挂起. 非阻塞:做一件事,尝试去做 2.传统IO模型 socket编程:
- HTTP Status 406 – Not Acceptable
前端调用这个方法报错: HTTP Status 406 – Not Acceptable Type Status Report Description The target resource does ...
- 静态资源上传至远程ftp服务器,ftp工具类封装
工具类,是一个单独的工程项目 提取必要信息至ftp.properties配置文件中 ftp_host=192.168.110.128 ftp_port=21 ftp_username=ftpuser ...
- httprunner学习25-文件上传multipart/form-data
前言 httprunner上传文件接口,其实跟requests上传文件的接口是一样的,之前在python接口系列里面有案例 python接口自动化16-multipart/form-data上传图片 ...
- 使用adb 命令(atrace)抓起systrace的方法。
adb shell atrace -c -b --async_start -z gfx 1. 执行查看adb shell atrace 功能 atrace --h atrace: invalid op ...
- 网络编程 TCP协议:三次握手,四次回收,反馈机制 socket套接字通信 粘包问题与解决方法
TCP协议:传输协议,基于端口工作 三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立 ...
- 宝塔https部署没成功的原因排查
今天ytkah在迁移一个客户网站的时候出了点问题,网站从旧的服务器(windows)换到新的服务器(阿里云centos 7,已经安装了宝塔面板),网站之前有用comodo的ssl证书,因为快要过期了, ...