problem

洛谷链接

solution

一个 AiA_iAi​ 只会影响一个 BiB_iBi​,BiB_iBi​ 之间的决定因素 AAA 是不会有交的。

所以如果相邻两个对同一个 BiB_iBi​ 影响的 A2i,A2i−1A_{2i},A_{2i-1}A2i​,A2i−1​ 都是确定的,那么 BiB_iBi​ 也就确定了。

这是不会对方案数产生贡献的,提前预处理掉这些位置,接下来的计算不考虑这些出现的值。

同时,如果都不确定,这些配对位置的值可以互换,即原本 −1-1−1 的位置是无序的,所以最后的答案要乘上一个阶乘。

BiB_iBi​ 是取较小值,容易想到从大到小考虑填的数,那么BiB_iBi​ 就仅由 A2i,A2i−1A_{2i},A_{2i-1}A2i​,A2i−1​ 后填的数决定。

下面将 A2i−1,A2iA_{2i-1},A_{2i}A2i−1​,A2i​ 没全填的称为“未配对”。

设 f(i,j,k):f(i,j,k):f(i,j,k): 已考虑到数第 iii 大时,有 jjj 个明确指定的数还未配对,有 kkk 个原本未知 −1-1−1 然后填了个数也还未配对 的方案数。

考虑由 f(i,j,k)f(i,j,k)f(i,j,k) 转移到 i+1i+1i+1,即 Ai+1A_{i+1}Ai+1​ 的配对情况。

  • 如果 Ai+1A_{i+1}Ai+1​ 原本是指定的数,Ai+1≠−1A_{i+1}\neq -1Ai+1​​=−1。

    • 可以和未知数配对,f(i,j,k)→f(i+1,j,k−1)f(i,j,k)\rightarrow f(i+1,j,k-1)f(i,j,k)→f(i+1,j,k−1)。
    • 可以新增一个已知数的未配对,f(i,j,k)→f(i,j+1,k)f(i,j,k)\rightarrow f(i,j+1,k)f(i,j,k)→f(i,j+1,k)。
  • 如果 Ai+1=−1A_{i+1}=-1Ai+1​=−1,未知。

    • 可以新增一个未知数的未配对,f(i,j,k)→f(i,j,k+1)f(i,j,k)\rightarrow f(i,j,k+1)f(i,j,k)→f(i,j,k+1)。

    • 可以和未知数配对,f(i,j,k)→f(i+1,j,k−1)f(i,j,k)\rightarrow f(i+1,j,k-1)f(i,j,k)→f(i+1,j,k−1)。

    • 可以和已知数配对,f(i,j,k)×j→f(i+1,j−1,k)f(i,j,k)\times j\rightarrow f(i+1,j-1,k)f(i,j,k)×j→f(i+1,j−1,k)。

      因为已知数的位置是固定的,所以 Ai+1A_{i+1}Ai+1​ 和 jjj 个已知数配对都是不同的情况。

      而和未知数的配对是不考虑 ×k\times k×k 的。本来位置就不固定,在最后的阶乘时候已经算入了,这里再乘就算重了。

初始状态 f(0,0,0)=1f(0,0,0)=1f(0,0,0)=1。

code

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
#define int long long
#define maxn 605
int n, m, cnt, fac;
int a[maxn], c[maxn], g[maxn];
int f[maxn][maxn][maxn];signed main() {scanf( "%lld", &n ), n <<= 1;for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i] );for( int i = 1;i <= n;i += 2 ) {if( a[i] == -1 and a[i + 1] == -1 ) cnt ++;else if( ~ a[i] and ~ a[i + 1] ) g[a[i]] = g[a[i + 1]] = 2;else {if( ~ a[i] ) g[a[i]] = 1;else g[a[i + 1]] = 1;}}for( fac = 1;cnt;fac = fac * cnt % mod, cnt -- );for( int i = n;i;i -- ) if( g[i] ^ 2 ) c[++ m] = i;f[0][0][0] = 1;for( int i = 0;i < m;i ++ )for( int j = 0;j <= n;j ++ )for( int k = 0;k <= n;k ++ )if( ! f[i][j][k] ) continue;else if( g[c[i + 1]] ) { //已知数( f[i + 1][j + 1][k] += f[i][j][k] ) %= mod; //新增一个未匹配的已知数if( k ) ( f[i + 1][j][k - 1] += f[i][j][k] ) %= mod; //和未知数匹配}else { //未知数( f[i + 1][j][k + 1] += f[i][j][k] ) %= mod; //新增一个未匹配的未知数if( j ) ( f[i + 1][j - 1][k] += f[i][j][k] * j % mod ) %= mod; //和已知数配对if( k ) ( f[i + 1][j][k - 1] += f[i][j][k] ) %= mod; //和未知数匹配}printf( "%lld\n", f[m][0][0] * fac % mod );return 0;
}

AtCoder4515 [AGC030F] Permutation and Minimum(dp)相关推荐

  1. 求三角形最大面积(DP)

    求三角形最大面积(DP) 在OJ上奇迹般WA了:WA:70. Why? #include <iostream> #include <string.h> using namesp ...

  2. LeetCode 编辑距离 II(DP)

    1. 题目 给你两个单词 s 和 t,请你计算出将 s 转换成 t 所使用的最少操作数. 你可以对一个单词进行如下两种操作: 删除一个字符 替换一个字符 注意: 不允许插入操作 题目保证有解 示例: ...

  3. LeetCode 1220. 统计元音字母序列的数目(DP)

    文章目录 1. 题目 2. 解题 1. 题目 给你一个整数 n,请你帮忙统计一下我们可以按下述规则形成多少个长度为 n 的字符串: - 字符串中的每个字符都应当是小写元音字母('a', 'e', 'i ...

  4. LeetCode 265. 粉刷房子 II(DP)

    文章目录 1. 题目 2. 解题 1. 题目 假如有一排房子,共 n 个,每个房子可以被粉刷成 k 种颜色中的一种,你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同. 当然,因为市场上不同颜色油 ...

  5. LeetCode 256. 粉刷房子(DP)

    文章目录 1. 题目 2. 解题 1. 题目 假如有一排房子,共 n 个,每个房子可以被粉刷成红色.蓝色或者绿色这三种颜色中的一种,你需要粉刷所有的房子并且使其与相邻的两个房子颜色不能相同. 当然,因 ...

  6. LeetCode 1223. 掷骰子模拟(DP)

    1. 题目 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数. 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[i](i 从 1 开始 ...

  7. LeetCode 1155. 掷骰子的N种方法(DP)

    1. 题目 这里有 d 个一样的骰子,每个骰子上都有 f 个面,分别标号为 1, 2, -, f. 我们约定:掷骰子的得到总点数为各骰子面朝上的数字的总和. 如果需要掷出的总点数为 target,请你 ...

  8. LeetCode 1139. 最大的以 1 为边界的正方形(DP)

    1. 题目 给你一个由若干 0 和 1 组成的二维网格 grid,请你找出边界全部由 1 组成的最大 正方形 子网格,并返回该子网格中的元素数量.如果不存在,则返回 0. 示例 1: 输入:grid ...

  9. 程序员面试金典 - 面试题 17.23. 最大黑方阵(DP)

    1. 题目 给定一个方阵,其中每个单元(像素)非黑即白. 设计一个算法,找出 4 条边皆为黑色像素的最大子方阵. 返回一个数组 [r, c, size] ,其中 r, c 分别代表子方阵左上角的行号和 ...

最新文章

  1. TPS54360 输入60V,输出3.5A降压开关电压
  2. vue打包后axios返回html,vue项目封装axios并访问接口
  3. C/C++中字符串与数字相互转换
  4. JDK自带内存及线程分析工具
  5. Together与Visual.Studio.NET的结合使用(一)
  6. windows自带录屏_电脑版免费的录屏软件有哪些?
  7. vc2012编译speex (没编过)
  8. 百度:一盗功成万网枯
  9. 水木周平戏说中国网络黑幽默!
  10. sx1278lora模块的常见问题解答
  11. 苹果微信更新不了最新版本_微信更新7.0版本,为何优先给iOS用户体验?这是在歧视安卓?...
  12. dubbo官网最新版导航
  13. 无人驾驶汽车系统入门(十一)——深度前馈网络,深度学习的正则化,交通信号识别
  14. 计算机基础知识考试模拟试题,计算机基础知识选择题考试必备考试真题模拟题...
  15. 高颜值时尚小巧蓝牙耳机推荐,女友生日过节最强送礼装备
  16. 最没灵魂的爬虫——Selenium 游戏信息的爬取与分析
  17. Thread.currentThread()与this的区别
  18. 高级语言程序设计(实验四)
  19. php bearer token,php-使用CURL设置Bearer令牌的正确方法
  20. OSChina 周四乱弹 ——不是二奶不是寡妇,老娘的男人是程序员

热门文章

  1. 12个关键词,告诉你到底什么是机器学习
  2. 我敢打赌,这世界没有python数据分析解决不了的问题
  3. 12星座程序员写代码
  4. 重点客户销售数据分析python_药品销售数据分析--python
  5. excel 如何替换带上标的文字_如何在Excel中批量提取中文汉字和英文字母
  6. unix系统mysql卸载教程_Linux操作系统下MySQL的卸载、安装全过程
  7. java并行流 阻塞主线程_多线程入门案例与java8的并行流
  8. python 廖雪峰数据分析统计服_廖雪峰python教程阅读量统计
  9. html如何显示上传进度条,HTML5 Ajax文件上传进度条如何显示
  10. [Spring5]IOC容器_Bean管理注解方式_创建对象