【题解】有限制的排列 [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]的更多相关文章

  1. 【题解】逆序排列 [51nod1020]

    [题解]逆序排列 [51nod1020] 传送门:逆序排列 \([51nod1020]\) [题目描述] 共 \(T\) 组测试点,每一组给出 \(2\) 个整数 \(n\) 和 \(k\),在 \( ...

  2. 题解 P4071 【[SDOI2016]排列计数】 (费马小定理求组合数 + 错排问题)

    luogu题目传送门! luogu博客通道! 这题要用到错排,先理解一下什么是错排: 问题:有一个数集A,里面有n个元素 a[i].求,如果将其打乱,有多少种方法使得所有第原来的i个数a[i]不在原来 ...

  3. hdu 5727 二分图+环排列

    Necklace Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  4. BZOJ 一句话题解

    菜鸡刷题记录 [题号:题解] 1008:简单排列组合 #include <bits/stdc++.h> using namespace std; #define ll long long ...

  5. AtCoder Grand Contest 055题解

    我太菜啦!!!md,第一题就把我卡死了...感觉对构造题不会再爱了... A - ABC Identity 先来看这个题吧,题意就是给定你一个字符串,让你将这个字符串最多分成6个子串,使得每个字符都在 ...

  6. BZOJ1653: [Usaco2006 Feb]Backward Digit Sums

    1653: [Usaco2006 Feb]Backward Digit Sums Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 207  Solved:  ...

  7. ZOJ Monthly, March 2013

    A题 题目大意:给出一棵树,一开始节点值均为0,先要求完成在线操作:将某子树所有节点值取反,或者查询某子树总点权. 题解:很基础的线段树题,既然两个操作都是子树操作,那么就先树链剖分一下,将子树操作转 ...

  8. CODEFORCES 25E Test

    题意 三个字符串,找一个字符串(它的子串含有以上三个字符串)使它的长度最短,输出此字符串的长度. 题解 先枚举字符串排列,直接KMP两两匹配,拼接即可...答案取最小值.. 常数巨大的丑陋代码 # i ...

  9. 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 ...

随机推荐

  1. maven 学习---Maven安装配置

    想要安装 Apache Maven 在Windows 系统上, 只需要下载 Maven 的 zip 文件,并将其解压到你想安装的目录,并配置 Windows 环境变量. 所需工具 : JDK 1.8 ...

  2. MYSQL GTID 复制

    MySQL5.7以后都基本用GTID方式复制了,相对于binlog和position号方式,在failover时候减少很多人工切换操作 GTID,global transaction identiti ...

  3. 微信小程序+php 授权登陆,完整代码

    先上图        实现流程: 1.授权登陆按钮和正文信息放到了同一个页面,未授权的时候显示登陆按钮,已授权的时候隐藏登陆按钮,显示正文信息,当然也可以授权和正文分开成两个页面,在授权页面的onlo ...

  4. SELECT语句基础

    列的查询 语法1-1 基本的SELECT语句 SELECT <列名>,... FROM <表名>; 语法1-2 查询出表中所有的列 SELECT * FROM  <表名& ...

  5. MySQL的rpm安装教程

    Linux 上安装 MySQL Linux平台上推荐使用RPM包来安装Mysql,MySQL AB提供了以下RPM包的下载地址: MySQL - MySQL服务器.你需要该选项,除非你只想连接运行在另 ...

  6. img border

  7. js提取DOM属性和设置DOM属性值

    <style type="text/css"> #div1{width:100px;height:100px;} #div2{background} </styl ...

  8. 第二阶段冲刺(个人)——four

    今天的的计划:选择功能界面的背景设计,使得整体效果看上去吸引眼球. 昨天做了什么?选择功能界面的选择框排版设计. 遇到的困难: 还是js的函数 设计,思路不是很清晰.

  9. Vinagre(Gnome Remote Desktop) cannot connect to RDP Server

    In a Sudden , this client cannot be used. Tried to install kdenetwork-krdc , then found there are de ...

  10. Native Clojure with GraalVM

    转自:https://www.innoq.com/en/blog/native-clojure-and-graalvm/ GraalVM is a fascinating piece of techn ...