题解:AT_arc184_d [ARC184D] Erase Balls 2D

posted on 2025-01-19 04:16:34 | under | source

先排序,被操作的点一定是下降子序列,直接算肯定会算重,考虑增强限制去重。

删去的点构成上下两个阶梯,不好处理,故考虑保留的点,是若干首尾相接的矩形。

注意到一个矩形若能被划为两个更小的矩形且点集不变,则会算重,所以要求不能发生这种情况。

现在不会算重了吗?对于最终统计的方案,考虑未被操作的点,若选其一必然多删去点;而操作点若取消操作,要么点集变了,反之不可能被统计(因为操作它点集不变)。

直接计数即可。\(O(n^3)\)

代码

#include<bits/stdc++.h>
using namespace std;

const int N = 3e2 + 5, mod = 998244353;
int n, s[N][N], f[N];
struct node{int x, y;} a[N];

inline bool chk(int x, int y){
	for(int i = x + 1; i < y; ++i)
		if(a[x].y > a[i].y && a[i].y > a[y].y && s[x][i] + s[i][y] - 1 == s[x][y]) return false;
	return true;
}
signed main(){
	cin >> n;
	for(int i = 1; i <= n; ++i) scanf("%lld%lld", &a[i].x, &a[i].y);
	a[n + 1] = {0, n + 1};
	a[n + 2] = {n + 1, 0};
	n += 2; 
	sort(a + 1, a + 1 + n, [](node A, node B){return A.x < B.x;}); 
	
	for(int i = 1; i <= n; ++i)
		for(int j = i + 1; j <= n; ++j)
			for(int k = i; k <= j; ++k)
				if(a[i].y >= a[k].y && a[k].y >= a[j].y) ++s[i][j]; 
	
	f[1] = 1;
	for(int i = 2; i <= n; ++i)
		for(int j = 1; j < i; ++j) 
			if(a[i].y < a[j].y && chk(j, i)) f[i] = (f[i] + f[j]) % mod;
	cout << f[n];
	return 0;
}

posted @ 2026-01-15 08:16  Zwi  阅读(3)  评论(0)    收藏  举报