ARC118E Avoid Permutations
题意
给定一个长度为 \(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的更多相关文章
- 47. Permutations II (JAVA)
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
- Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
- [LeetCode] Permutations II 全排列之二
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
- [LeetCode] Permutations 全排列
Given a collection of numbers, return all possible permutations. For example,[1,2,3] have the follow ...
- POJ2369 Permutations(置换的周期)
链接:http://poj.org/problem?id=2369 Permutations Time Limit: 1000MS Memory Limit: 65536K Total Submi ...
- String源码中的"avoid getfield opcode"
引言: 之前一篇文章梳理了String的不变性原则,还提到了一段源码中注释"avoid getfield opcode",当时通过查阅资料发现,这是为了防止 getfield(获取 ...
- 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 ...
- Permutations
Permutations Given a collection of distinct numbers, return all possible permutations. For example,[ ...
- 【leetcode】Permutations
题目描述: Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the ...
- [leetcode] 47. Permutations II
Given a collection of numbers that might contain duplicates, return all possible unique permutations ...
随机推荐
- UnrealEngine - 反射系统分析
1. 反射 什么是反射?或者说反射能做什么,简单来说,反射可以提供一种能力,能够在运行时动态获取对象的成员信息,如成员函数,成员变量. UE 在其反射系统上支持了许多功能,如: 编辑器中可供编辑的属性 ...
- 关于Cookie要懂的知识
☞演示 什么是Cookie? http是一个无状态协议,它不对之前发生过的请求和响应的状态进行管理.这样就可能导致,我们登陆一个网站后,每次跳转新页面,之前的登陆状态都不能被记住,要重新登陆等问题. ...
- Python GDAL库在Anaconda环境中的配置
本文介绍在Anaconda环境下,安装Python中栅格.矢量等地理数据处理库GDAL的方法. 需要注意的是,本文介绍基于conda install命令直接联网安装GDAL库的方法:这一方法有 ...
- YII2.0的文件上传, 并把文件名称重新编译
/** *@Action 文件上传示例 *@这里我们演示的是一个YII2.0的文件上传, 并把文件名称重新编译 *@我们上传的是一个叫 photo 的jpg和png格式的文件 */ Controlle ...
- DevOps、SRE、平台工程的区别
DevOps.SRE和平台工程的概念在不同时期出现,并由不同的个人和组织开发. DevOps作为一个概念是由Patrick Debois和Andrew Shafer在2009年的敏捷会议上提出的.他们 ...
- node使用react项目启动错误TSError: ⨯ Unable to compile TypeScript:
1.错误内容 return new TSError(diagnosticText, diagnosticCodes) ^ TSError: ⨯ Unable to compile TypeScript ...
- Typora用法:
Typora用法: 一:标题 模板: #+空格+标题名+回车 一级标题 二级标题 三级标题 四级标题 五级标题 二:字体 加粗 斜体 斜体加粗 删除线(esc键下面的那个键) 上标:我是上标 下表:我 ...
- JS 实现关键字文本搜索 高亮显示
示例: 利用字符串的 split 方法,通过搜索的关键字分割成数组 在利用数组的 join 方法拼接成字符串 我是利用mock的省份 1 <template> 2 <div cl ...
- 2022-07-09:总长度为n的数组中,所有长度为k的子序列里,有多少子序列的和为偶数?
2022-07-09:总长度为n的数组中,所有长度为k的子序列里,有多少子序列的和为偶数? 答案2022-07-09: 方法一:递归,要i还是不要i. 方法二:动态规划.需要两张dp表. 代码用rus ...
- simplejwt配置大全
# simplejwt配置大全SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5), # 设置token有效时间 'REFRESH_ ...