AT_arc184_d [ARC184D] Erase Balls 2D

news/2024/9/29 20:53:44

AT_arc184_d [ARC184D] Erase Balls 2D

首先,假定我们选定的行为 \(i_1,i_2,\cdots,i_k\),并有 \(i_1<i_2<\cdots<i_k\),则 \(p_{i_1}>p_{i_2}>\cdots>p_{i_k}\)。其中 \(p_x\) 表示 \((x,p_x)\) 的位置上有点。

最终状态形如下图。显然,这种状态与操作顺序无关。

为了方便统计,加入 \((0,n+1)\)\((n+1,0)\),并钦定这两个点必须选上。

加入枚举选的点集 \(S=\{(i_1,p_{i_1}),(i_2,p_{i_2})\cdots,(i_k,p_{i_k})\}\),令最终保留的点集为 \(T\)。直接统计 \(S\) 的方案会算重,考虑对于每个点集 \(T\) 设定一个唯一的点集 \(S\) 与之对应。

对于每个 \(T\),一般的想法是选择 \(|S|\) 极值下的情况,考虑这两种方法是否成功:

  1. 选取 \(|S|\) 最少,考虑一例子:\((1,2),(2,1),(3,3)\),选取 \(S=\{(1,2)\}\) 或是 \(\{(2,1)\}\) 所对应的保留的点集 \(T\) 是相同,所以统计起来还需要额外增加条件。

  2. 选取 \(|S|\) 最多,这个 \(S\) 显然是唯一的。具体的,可以考虑一个结束状态 \(T\),通过不断将 \((x,p_x)\) 加入 \(S\) 中的方法,得到唯一性。

这样的话就比较容易了,考虑令 \(f_{i}\) 表示考虑了前 \(i\) 个,\((i,p_i) \in S\) 的总方案数。每次枚举上一个点 \(j\),判断 \((j,p_j)\)\((i,p_i)\) 所得到的矩形内的点是否满足:任意选择一个点,都会使得有一个矩形内的点被删除。

这个判断容易的,用前缀最小值与后缀最大值 \(O(n)\) 判断即可。

复杂度 \(O(n^3)\)。感觉 2804 的评分有点虚高……

#include <bits/stdc++.h>
using namespace std;#define vi vector<int>
#define pb push_back
#define pii pair<int,int>
#define mkp make_pairint rd() {int x = 0, f = 1;char ch = getchar();while (!('0' <= ch && ch <= '9')) {if (ch == '-') f = -1; ch = getchar();}while ('0' <= ch && ch <= '9') {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();}return x * f;
}void wr(int x) {if (x < 0) putchar('-'), x = -x;if (x >= 10) wr(x / 10); putchar(x % 10 + '0');
}const int N = 310;
const int mod = 998244353;int f[N];
int n, x[N], y[N], pos[N];
int cnt, b[N], preb[N], sufb[N];bool check() {for (int i = 1; i <= cnt; ++i)preb[i] = sufb[i] = b[i];for (int i = 2; i <= cnt; ++i)preb[i] = min(preb[i - 1], preb[i]);for (int i = cnt - 1; i >= 1; --i)sufb[i] = max(sufb[i + 1], sufb[i]);for (int i = 2; i <= cnt - 1; ++i) {if (preb[i] >= b[i] && b[i] >= sufb[i]) return false; }return true;
}int main() {ios::sync_with_stdio(false); cin.tie(0);cin >> n;for (int i = 1; i <= n; ++i) {int x, y; cin >> x >> y; pos[x] = y; }f[0] = 1; pos[0] = n + 1;for (int i = 1; i <= n + 1; ++i) {for (int j = 0; j < i; ++j) {if (pos[i] > pos[j]) continue; cnt = 0; for (int k = j; k <= i; ++k) {if (pos[i] <= pos[k] && pos[k] <= pos[j])b[++cnt] = pos[k]; }if (check()) f[i] = (f[i] + f[j]) % mod; }}cout << f[n + 1] << endl; return 0; 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/66309.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

「Wdoi-(-1)」恋弹者们的黑集市

「Wdoi-(-1)」恋弹者们的黑集市 魔理沙有两种方法移动这个骰子:将骰子向下一列翻转,或者向下一行翻转。值得注意的是,翻转骰子后,骰子每面上的数字就会随着翻滚而改变。现在魔理沙需要将骰子滚动至第 \(n\) 行第 \(m\) 列。 魔理沙的分数被定义为,所有时刻,骰子与棋盘上的…

腾讯企业邮箱(企业微信邮箱)迁移到microsoft 365(office 365)

1.迁移前准备(腾讯企业邮箱)1.如果你是企业管理员,首先看一下企业邮箱后台,是否已关闭 登陆安全2.登录要迁移的个人邮箱后台,关闭安全登录、开启IMAP服务和相关选项,以及为邮箱设置一个密码 2.开始迁移1.登录microsoft 365管理后台(https://admin.exchange.microsoft.com…

micropython +ESP32+ sht30 温湿度模块

SHT30 1)查找SHT30芯片资料 https://www.szlcsc.com 2)根据芯片资料,查得地址为 0x44 或 0x45 选 Measurement Commands for Single Shot Data Acquisition Mode, 命令为 0x2c10 3)连线SHT30 ESP32 D1(SCL) 4D2(SDA) 5 G …

系统固态扩容-全小白操作示意 不需要BIOS

机械革命有两个插槽,我有一个500G(系统盘)一个1T的固态,由于1.5T的固态都快用完了,所以买了一个2T的固态,将1T的内容迁移到2T中,将500G的迁移到1T中。 为了防止内容丢失先将500G系统盘做了备份,用的傲梅轻松备份。 1T->2T 然后就是将2T的固态用绿联的固态盒子先当做移…

2024-2025-1 20241318 《计算机基础与程序设计》第一周学习总结

这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(如2024-2025-1计算机基础与程序设计第一周作业)这个作业的目标 阅读浏览教材《计算机科学概论》并提出自己的问题,基于AI进行学习作业正文 ... 本博…

移除元素

第一个想法就是利用两个for循环暴力解决 #include <iostream> #include <vector> using namespace std; class Solution { public: int removeElement(vector<int>& nums, int val) { int size = nums.size(); int writeIndex = 0; // 用来记录…

学年(2024-2025-1) 学号(20241424)《计算机基础与程序设计》第一周学习总结

学年(2024-2025) 学号(20241424)《计算机基础与程序设计》第一周学习总结 作业信息 |这个作业属于2024-2025-1-计算机基础与程序设计)| |-- |-- | |这个作业要求在2024-2025-1计算机基础与程序设计第一周作业)| |这个作业的目标|<参考上面的学习总结模板,把学习过程通…

Qt - 文件操作3

8. QSettings8.1 简介 用户通常希望应用程序在会话中记住它的设置(窗口大小和位置,选项等)。 这些信息通常存储在Windows上的系统注册表中(HKEY_CURRENT_USERSoftware/MySoft ),以及macOS和iOS上的属性列表文件中。 在Unix系统上,在缺乏标准的情况下,许多应用程序(包括KDE应…