题意

给定一个长度为 \(n\) 的排列 \(p\),在一个 \((n + 2)\times(n + 2)\) 的网格上,禁止通过 \((i, p_i)\) 这些点,每次只能向上或右走一格,从 \((0, 0)\) 走到 \((n + 1, n + 1)\) 的方案数,定义为排列的权值。给定一个不完整的排列,对于所有补全排列的方案,计算权值和。

数据范围:\(1\le n \le 200\)。

做法

这题并不需要容斥。

考虑计算对于某一条路径,有多少排列满足没有点在路径上。那么正常 DP 路径,在 \((i, j)\) 这个点向上转移到 \((i, j + 1)\) 的时候决策 \(y = j + 1\) 这一行左侧是否放置一个物品、放置在哪个位置,同时记录当前位置左下角区域总共放置了多少障碍。DP 状态设计为 \(f_{i, j, k, 0/1, 0/1}\) 表示在 \((i, j)\) 左下角放了 \(k\) 个障碍,这一行左边是不是已经放了东西,这一列下面是不是已经放了东西。转移需要一些讨论。时间复杂度 \(\Theta(n^3)\)。

代码

// Author: kyEEcccccc

#include <bits/stdc++.h>

using namespace std;

using LL = long long;
using ULL = unsigned long long; #define F(i, l, r) for (int i = (l); i <= (r); ++i)
#define FF(i, r, l) for (int i = (r); i >= (l); --i)
#define MAX(a, b) ((a) = max(a, b))
#define MIN(a, b) ((a) = min(a, b))
#define SZ(a) ((int)((a).size()) - 1) const int N = 205, MOD = 998244353; int n, p[N], q[N];
int toti[N], totj[N];
LL f[N][N][N][2][2]; signed main(void)
{
// freopen(".in", "r", stdin);
// freopen(".out", "w", stdout);
ios::sync_with_stdio(0), cin.tie(nullptr); cin >> n;
F(i, 1, n)
{
cin >> p[i];
if (p[i] != -1) q[p[i]] = i;
}
F(i, 1, n)
{
toti[i] = toti[i - 1];
totj[i] = totj[i - 1];
if (p[i] <= 0) toti[i] += 1;
if (q[i] <= 0) totj[i] += 1;
}
toti[n + 1] = toti[n];
totj[n + 1] = totj[n]; F(i, 0, n + 1) f[i][0][0][0][0] = f[0][i][0][0][0] = 1;
F(i, 1, n + 1) F(j, 1, n + 1) F(k, 0, min(toti[i], totj[j])) F(a, 0, 1) F(b, 0, 1)
{
LL &res = f[i][j][k][a][b];
if (((a == 1 && p[i] <= 0) || (b == 1 && q[j] <= 0)) && k == 0) continue;
if ((i == n + 1 && a == 1) || (j == n + 1 && b == 1)) continue;
if (p[i] > 0 && p[i] == j) continue;
if (p[i] > 0 && ((p[i] < j && a == 0) || (p[i] > j && a == 1))) continue;
if (q[j] > 0 && ((q[j] < i && b == 0) || (q[j] > i && b == 1))) continue; if (a == 0)
{
res = (res + f[i - 1][j][k][0][b] + f[i - 1][j][k][1][b]) % MOD;
}
else
{
if (p[i] > 0)
{
res = (res + f[i - 1][j][k][0][b] + f[i - 1][j][k][1][b]) % MOD;
}
else if (q[j] <= 0)
{
res = (res + (f[i - 1][j][k - 1][0][b] + f[i - 1][j][k - 1][1][b])
* (totj[j - 1] - k + 1 + b)) % MOD;
}
else
{
res = (res + (f[i - 1][j][k - 1][0][b] + f[i - 1][j][k - 1][1][b])
* (totj[j - 1] - k + 1)) % MOD;
}
} if (b == 0)
{
res = (res + f[i][j - 1][k][a][0] + f[i][j - 1][k][a][1]) % MOD;
}
else
{
if (q[j] > 0)
{
res = (res + f[i][j - 1][k][a][0] + f[i][j - 1][k][a][1]) % MOD;
}
else if (p[i] <= 0)
{
res = (res + (f[i][j - 1][k - 1][a][0] + f[i][j - 1][k - 1][a][1])
* (toti[i - 1] - k + 1 + a)) % MOD;
}
else
{
res = (res + (f[i][j - 1][k - 1][a][0] + f[i][j - 1][k - 1][a][1])
* (toti[i - 1] - k + 1)) % MOD;
}
}
} cout << f[n + 1][n + 1][toti[n]][0][0] << endl; return 0;
}

ARC118E Avoid Permutations的更多相关文章

  1. 47. Permutations II (JAVA)

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  2. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  3. [LeetCode] Permutations II 全排列之二

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  4. [LeetCode] Permutations 全排列

    Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the follow ...

  5. POJ2369 Permutations(置换的周期)

    链接:http://poj.org/problem?id=2369 Permutations Time Limit: 1000MS   Memory Limit: 65536K Total Submi ...

  6. String源码中的"avoid getfield opcode"

    引言: 之前一篇文章梳理了String的不变性原则,还提到了一段源码中注释"avoid getfield opcode",当时通过查阅资料发现,这是为了防止 getfield(获取 ...

  7. 10 Biggest Business Mistakes That Every Entrepreneur Should Avoid

    原文链接:http://www.huffingtonpost.com/syed-balkhi/10-biggest-business-mista_b_7626978.html When I start ...

  8. Permutations

    Permutations Given a collection of distinct numbers, return all possible permutations. For example,[ ...

  9. 【leetcode】Permutations

    题目描述: Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the ...

  10. [leetcode] 47. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

随机推荐

  1. 关于关键字final用法以及意义

    *   * 1.final可以用来修饰的结构:类.方法.变量  *   * 2.final用来修饰一个类:此类不能被其他类所继承.  *           比如:String类.System类.St ...

  2. 技术分享:Proxy-Pool代理池搭建IP代理

    技术分享:Proxy-Pool代理池搭建IP代理 前言本章内容仅供参考,不涉及实际使用,主要使用Python环境和Redis数据库进行环境搭建,工具网盘存储如下,有问题可以私聊我.网址:https:/ ...

  3. Jmix 如何将外部数据直接显示在界面?

    企业级应用中,通常一个业务系统并不是孤立存在的,而是需要与企业.部门或者是外部的已有系统进行集成.一般而言,系统集成的数据和接口交互方式通常有以下几种: 文件传输:通过文件传输的方式将数据传递给其他系 ...

  4. [MyBatis]MyBatis问题及解决方案记录

    1字节的UTF-8序列的字节1无效 - CSDN 手动将<?xml version="1.0" encoding="UTF-8"?>中的UTF-8更 ...

  5. 开心档之MySQL 序列使用

      MySQL 序列使用 MySQL 序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现. 本章我们将 ...

  6. java-io FileInputStream文件拷贝

    1.编写代码 main方法: public static void main(String[] args) throws IOException { String pathFileUrl =" ...

  7. python数据可视化神库:Matplotlib快速入门

    Matplotlib易于使用,是Python中了不起的可视化库.它建立在NumPy数组的基础上,旨在与更广泛的SciPy堆栈一起工作,并由几个图组成:线图.条形图.散点图.直方图等. 快速入门 imp ...

  8. 读《图解HTTP》

    最近读了一本书<图解HTTP>,读完后在大体上对HTTP协议有了更深层次的了解.以下是我以前不懂的问题,通过阅读此书后,这些问题都有了答案: 问题: URI和URL的区别? cookie到 ...

  9. Latex-beamer的教程

    Beamer头文件 Latex是一个非常精确且高效的排版工具,其中的beamer作为一个非常强大的模块承担着PPT任务的排版 首先引入头文件来开始: \documentclass{beamer} %h ...

  10. 2023-03-03:请用go语言调用ffmpeg,摄像头捕获并编码为h264文件,不管音频。

    2023-03-03:请用go语言调用ffmpeg,摄像头捕获并编码为h264文件,不管音频. 答案2023-03-03: 使用 github.com/moonfdd/ffmpeg-go 库. 先用如 ...