AT_arc127_e Priority Queue

题解:

我们重新定义题意,发现也可以表示为一个由蓝球和黄球组成的序列:

然后每个删除操作是一个竖杠,他会删除区间中的最大值,我们标记为那个黄球。每个球上有一个数,这个序列是一个 \(1,2,\ldots,n\) 的排列。
由于最后的得到的只是蓝色球的集合,我们就可以将所有的蓝色球和黄色球分别从小到大排序,从而得到无序性。然后把黄色球移到最前面:(可以证明,对于排序后的 \(1\)\(n\) 的数列,一定可以找到唯一对应的原序列)

这样我们就可以认为成多个黄色球为末尾的块了。(这里产生了一个限制,就是这个块末尾的黄色球的数要大于所有在他这个块的蓝色球的数,不然就会被顶替掉)

这时我们就可以对数值进行匹配黄球还是蓝球了。对于每个黄球自然是有限制,那就是第 \(i\) 个黄球的数值必须 $\ge $ 在原数列是 \(1,2,\ldots,n\) 时黄球的对应数(因为这已经是最小了再小就不行了)。

这时我们考虑 dp。定义 \(dp_{i,j}\) 表示已经考虑到了 \(i\) 这个数值(从后往前),填入到了后第 \(j\) 个黄球的方案数。
则我们考虑转移。对于每个球,我们可以把它们染成蓝球或者是黄球。

  • 如果要填入蓝球,我们需要保证后面的黄球可以填下去。所以需要当前填的 \(i-1 \ge pos_{j-1}\),即使得第 \(j\) 个黄球得以放入。
  • 如果填入黄球,由于蓝球已经考虑过能不能填的情况,我们只要还有黄球需要填时填入黄球就行。

Code:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5010, mod = 998244353;
int A, B, f[N][N];
int st[N], top, now;
int pos[N], Y;
void add(int &a, int b) {a = (a + b) % mod;}
int main() {
	scanf("%d%d", &A, &B);
	for(int _ = 1; _ <= A + B; _++) {
		int op; scanf("%d", &op);
		if(op == 1) st[++top] = ++now;
		else pos[++Y] = st[top--];
	}
	sort(pos + 1, pos + 1 + B);
	f[A + 1][B + 1] = 1;
	for(int i = A + 1; i > 1; i--) {
		for(int j = B + 1; j; j--) {
			if(i - 1 > pos[j - 1]) add(f[i - 1][j], f[i][j]);
			if(j > 1) add(f[i - 1][j - 1], f[i][j]);
		}
	}
	printf("%d\n", f[1][1]);
	return 0;
}
posted @ 2026-08-09 16:23  OIerYang  阅读(3)  评论(0)    收藏  举报