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 ...
随机推荐
- ACM-DP-数塔问题
Description 在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的: 有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少? 已经告 ...
- k8s加入新的master节点出现etcd检查失败
背景: 昨天在建立好新的集群后,出现了新的问题,其中的一台master节点无法正常工作.虽然可以正常使用,但是就出现了单点故障,今天在修复时出现了etcd健康检查自检没通过. ...
- 在Ubuntu中安装Samba文件服务
点击蓝字 关注我们 First Frost 在Ubuntu中安装Samba文件服务 Samba是一个能让Linux系统应用Microsoft网络通讯协议的软件,而SMB是Server Message ...
- 二进制安装Kubernetes(k8s) v1.24.0 IPv4/IPv6双栈 (三主俩从)
二进制安装Kubernetes(k8s) v1.24.0 IPv4/IPv6双栈 (三主俩从) Kubernetes 开源不易,帮忙点个star,谢谢了 介绍 kubernetes二进制安装 后续尽可 ...
- C++ sizeof与strlen,并借此明晰内存对齐
前言 sizeof()与strlen()都是为了获取对象的长度.在正常编写C++的算法程序代码时,可能这两个都很少用到,因为各种stl容器的封装已经给了我们很大的便利,比如我们在想要获取自定义的vec ...
- C盘爆满的解决方法,不用删除文件,使用分区助手无损增加内存
一.分区助手傲梅科技 对于我们C盘内存不足的来说,老师推荐的yyds. 我的内存C盘历史最低是900多M,1.5G还是多的,经过我不断的删除文件,发现没什么用,电脑用久了C盘文件占内存自然就多了!!改 ...
- Flowable启动报错problem during schema upgrade&&couldn‘t upgrade db schema:
1.错误信息 problem during schema upgrade, statement alter table ACT_RU_VARIABLE add column SCOPE_ID_ var ...
- MySQL高频面试题
什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据.你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列).行代表每一行数据,列代表该行中的每个值.列上的值是 ...
- ai问答:使用 Vue3 组合式API 和 TS 封装 websocket 断线重连
这是一个使用 Vue3 组合式 API 和 TS 封装 websocket 的例子 这个组件在 setup 中: 创建了一个 WebSocket 连接 定义了 sendMessage 方法发送消息 监 ...
- Laf Assistant:云开发从未如此爽快!
原文链接:https://forum.laf.run/d/67 工欲善其事,必先利其器.在编写代码时,IDE 也是我们不可或缺的.它可以让我们更高效地完成代码编写,提高开发效率.因此,IDE 是我们编 ...