【题解】有限制的排列 [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 ...
随机推荐
- XSS靶场练习
0x00:前言 一个XSS练习平台,闯关形式,一共20关 0x01:开始 第一行都是代码插入点,下面几行是payloads(插入点和payloads中间空一行) LV1 <script>a ...
- 个人项目-wc
个人项目-WC (C语言) 一.Github地址:https://github.com/Lin-J-F/WC 二.PSP表格 PSP2.1 Personal Software Process St ...
- Linux的基本指令(2)-Linux从入门到精通第三天(非原创)
文章大纲 一.高级指令二.练习题三.学习资料下载四.参考文章 一.高级指令 1. hostname指令 作用:操作服务器的主机名(读取.设置)语法1:#hostname 含义:表示输出完整的主机名 ...
- docker gitlab-runner的安装
参考: Run GitLab Runner in a container 前面介绍了gitlab-ce的安装,下面是gitlab-runner的安装,同样还是安装docker版本. 1.下载 dock ...
- 关于pytest的命令行传参
#conftest.py import pytest def pytest_addoption(parser): #parser:用户命令行参数与ini文件值的解析器 # group = parser ...
- WPF系列 —— 控件添加依赖属性(转)
WPF系列 —— 控件添加依赖属性 依赖属性的概念,用途 ,如何新建与使用.本文用做一个自定义TimePicker控件来演示WPF的依赖属性的简单应用. 先上TimePicker的一个效果图. 概念 ...
- C#使用Xamarin开发移动应用 ---- 系列文章
C#使用Xamarin开发移动应用 C#使用Xamarin开发可移植移动应用终章(11.获取设备信息与常用组件,开源一个可开发模版.) C#使用Xamarin开发可移植移动应用进阶篇(10.综合演练, ...
- 201671010450-姚玉婷-实验十四 团队项目评审&课程学习总结
项目 内容 所属科目 软件工程http://www.cnblogs.com/nwnu-daizh 作业要求 https://www.cnblogs.com/nwnu-daizh/p/11093584. ...
- ReSharper安装
ReSharper是一个JetBrains公司出品的著名的代码生成工具,其能帮助Microsoft Visual Studio成为一个更佳的IDE.它包括一系列丰富的能大大增加C#和Visual Ba ...
- offsetHeight在不同的浏览器下取值不同
今天在调js的时候,发现firefox和IE在取document.body.offsetHeight的值的时候结果不一样.上网查了一下,发现如下结果: 这四种浏览器分别为IE(Internet E ...