AGC030F - Permutation and Minimum
https://atcoder.jp/contests/agc030/tasks/agc030_f
题解
我们先把这个排列从\(1 \sim 2n\)表达出来,然后题面中的每一对数我们可以用一条线把他们连起来,那么在序列中表达出的值是这条线的左端点。
如果一开始每个数都没有限制的话,我们则需要求有哪些数会成为左端点,这个其实就是卡特兰数,求答案的话还需要求一个阶乘。
现在有一些位置有了限制,我们就把有限制的位置成为特殊位置。
还是从\(1\sim 2n\)这个序列上考虑,因为我们的贡献是在左端点产生,所以我们设\(dp[i][j][k]\)表示做到\(i\),有\(j\)个普通点没有被匹配,有\(k\)个特殊点没有被匹配。
普通点可以任意匹配,特殊点只能匹配普通点。
如果普通点匹配了特殊点,那么它的位置已经确定了,所以最后我们要乘上普通配普通的对数的阶乘。
代码
#include<bits/stdc++.h>
#define N 602
using namespace std;
typedef long long ll;
int n,now,a[N],sm;
int tag[N];
ll jie[N],dp[2][302][302];
const int mod=1e9+7;
inline void MOD(ll &x){x=x>=mod?x-mod:x;}
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
int main(){
n=rd();
sm=n*2;
int cnt=0;
for(int i=1;i<=sm;++i){
a[i]=rd();
if(a[i]!=-1)tag[a[i]]=1;
if(i%2==0&&a[i]!=-1&&a[i-1]!=-1){
tag[a[i]]=-1;
tag[a[i-1]]=-1;
}
if(i%2==0&&a[i]==-1&&a[i-1]==-1)cnt++;
}
jie[0]=1;
for(int i=1;i<=sm;++i)jie[i]=jie[i-1]*i%mod;
dp[1][0][0]=1;
int now=1,pre=0;
for(int i=sm;i>=1;--i)if(tag[i]!=-1){
swap(now,pre);
memset(dp[now],0,sizeof(dp[now]));
for(int j=0;j<=n;++j)
for(int k=0;j+k<=n;++k)if(dp[pre][j][k]){
if(tag[i]){
MOD(dp[now][j][k+1]+=dp[pre][j][k]);
if(j)MOD(dp[now][j-1][k]+=dp[pre][j][k]);
}
else{
MOD(dp[now][j+1][k]+=dp[pre][j][k]);
if(j)MOD(dp[now][j-1][k]+=dp[pre][j][k]);
if(k)MOD(dp[now][j][k-1]+=dp[pre][j][k]*k%mod);
}
}
}
printf("%lld",dp[now][0][0]*jie[cnt]%mod);
return 0;
}
AGC030F - Permutation and Minimum的更多相关文章
- 【agc030f】Permutation and Minimum(动态规划)
[agc030f]Permutation and Minimum(动态规划) 题面 atcoder 给定一个长度为\(2n\)的残缺的排列\(A\),定义\(b_i=min\{A_{2i-1},A_{ ...
- 【AGC030F】Permutation and Minimum DP
题目大意 有一个长度为序列 \(a\),其中某些位置的值是 \(-1\). 你要把 \(a\) 补成一个排列. 定义 \(b_i=\min(a_{2i-1},a_{2i})\),求有多少种可能的 \( ...
- 【AGC030F】Permutation and Minimum(DP)
题目链接 题解 首先可以想到分组后,去掉两边都填了数的组. 然后就会剩下\((-1,-1)\)和\((-1,x)\)或\((x,-1)\)这两种情况 因为是最小值序列的情况数,我们可以考虑从大到小填数 ...
- AtCoder Grand Contest 030 (AGC030) F - Permutation and Minimum 动态规划
原文链接www.cnblogs.com/zhouzhendong/p/AGC030F.html 草率题解 对于每两个相邻位置,把他们拿出来. 如果这两个相邻位置都有确定的值,那么不管他. 然后把所有的 ...
- Atcoder Grand Contest 030 F - Permutation and Minimum(DP)
洛谷题面传送门 & Atcoder 题面传送门 12 天以前做的题了,到现在才补/yun 做了一晚上+一早上终于 AC 了,写篇题解纪念一下 首先考虑如果全是 \(-1\) 怎么处理.由于我 ...
- AtCoder Grand Contest 030题解
第一次套刷AtCoder 体验良好 传送门 Poisonous Cookies cout<<b+min(c,a+b+); Tree Burning 难度跨度有点大啊 可以证明当第一次转向之 ...
- AGC030 简要题解
A - Poisonous Cookies 题意 有\(A\)个能解毒的普通饼干,\(B\)个能解毒的美味饼干,\(C\)个有毒的美味饼干,求最多能吃多少个美味饼干,每次吃完有毒的饼干后要解毒后才能继 ...
- 【AtCoder】AGC030
A - Poisonous Cookies 有毒还吃,有毒吧 #include <bits/stdc++.h> #define fi first #define se second #de ...
- [LeetCode] Minimum Window Substring 最小窗口子串
Given a string S and a string T, find the minimum window in S which will contain all the characters ...
随机推荐
- xmake从入门到精通10:多个子工程目标的依赖配置
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验. 本文主要详细讲解下,如果在一个项目中维护和生成多个 ...
- MySQL数据库生成数据库说明文档
在半年多前为一个MySQL数据库生成过数据库说明文档,今天要重新生成一份,但是发现完全不记得当时是怎么生成的,只能在网上搜索重来一遍,所以今天特意把这个过程记录一下. 一.安装 使用MySQL数据库表 ...
- spring-第N篇整合SSM,即Mybatis+Spring+Spring MVC
1.Mybatis的配置使用 1>Jar包:mybatis-3.4.5.jar.mysql-connector-6.0.2或者ojdbc6-11.2.0.4.jar. 2>编写conf.x ...
- Apache 强制SSL访问
RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R ...
- MySQL时间戳加减转日期
一.时间戳计算前N天后N天并转化为日期,本例是将某个时间戳转为日期,并计算出与该日期前后相差7天的日期: , , , DAY)as 'after'; 输出: # before, now, after ...
- 前端UI库推荐(pc和移动)
此推荐个人喜好,不喜勿喷. 1. pc 端 elementUI (生态强大,样式生硬) iview (推荐,组件丰富) bootStrap layUI easyUi 2. 移动端 mintUI ant ...
- 在Visual studio 2017中使用EF6连接MySQL
在Visual studio 2017中使用EF6连接Mysql ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) ...
- linux基本命令vi和vim使用详细介绍
vi使用方法详细介绍 vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指令.由于对Unix及Linux系统的任何版 ...
- HTML文本格式化标签(Formatting)
<b>粗体文本</b> <code>计算机代码</code> <em>强调文本</em> <i>斜体文本</i ...
- HTML回顾之表单和列表
FORM HTML 表单 表单是一个包含表单元素的区域. 表单元素是允许用户在表单中输入内容,比如:文本域(textarea).下拉列表.单选框(radio-buttons).复选框(checkbo ...