P13573 [CCPC 2024 重庆站] Pico Park
题意:
游戏中,有 \(n\le 500\) 名玩家,依次站在数轴的 \(1,2,3, \dots, n\) 处,第 \(i\) 名玩家有一个面向的方向 \(d_i\),为向左或向右。
每名玩家手里有一把缩小枪,玩家会按照一个排列 \(p\) 的顺序行动,当轮到玩家 \(x\) 行动时:
- 若该玩家已经被缩小,则其不会进行任何行动。
- 否则,其会向其面对的方向发射子弹,子弹会击中面对方向的第一个未被缩小的玩家(若面对方向已经没有玩家,则不会击中任何人)。被击中的玩家会立刻被缩小。
对于每一个 \(1\leq k\leq n\),有多少个排列会使最终剩余 \(k\) 个未被缩小的玩家?
由于答案很大,你只需要输出答案对 \(998244353\) 取模后的值。
思路:
因为每次射击只能攻击与自己最近的人,刻画生死关系:\(x\) 向 \(y\) 连边当且仅当 \(x\) 杀死 \(y\),可以发现删除操作一定是若干个不交链,且每条链的 编号区间 \([l,r]\) 连续且不交 。但是我们无法保证每一个编号区间都可以形成一条合法的生死关系。
考虑相邻两个人会被如何消除:若出现了 \(s_i=L \and s_{i+1}=R\) ,那么显然会至少导致两个人存活,所以一个编号序列中不可能存在 \(LR\) 类状物。由此可得:一个合法的编号区间所对应的字符串一定形如:\(R\dots RL\dots L\)
因为一条链上最终只能存活一个人,加上我们在前面提到的生死链不交,所以考虑 区间 dp
考虑一个幸存者 \(x\) 在一个合法编号区间 \([l,r]\and r-l+1\ge 2\) 的位置:
-
\(x=l\) :
-
当 \(S_x=L\) 时,无论如何都无法存活
-
当\(S_x=R\) 时,删去该端点,使编号区间变成 \([l+1,r]\) ,仍然会是一个合法编号区间,显然可以先让 \([l+1,r]\) 删到只剩一个幸存者 \(y\),然后再让 \(x\) 攻击 \(y\)
-
-
\(l< x<r\)
把当前区间分成三段:\([l,x-1],x,[x+1,r]\) ,因为 \(x\) 未被删除,所以区间 \([l,x-1]\) 内的攻击无法攻击到 \([x+1,r]\) ,因此可以把这条链拆成独立的两条链 \([l,x-1],[x+1,r]\) ,因为一条链最终只能存活一个人,因此在 \(x\) 的两边各有一个人等待删除,但 \(x\) 的出度只有 \(1\) ,因此至少有两个人存活。
-
\(x=r\) ,同 \(x=l\)
所以一个合法编号区间的幸存者只会存在于区间的两个端点,我们设 \(g_{l,r}\) 表示 \([l,r]\) 是合法区间的排列方案数。有转移
注意到我们此时没有安排第一个被删除的人在排列中的位置,因为第一个人不能攻击到区间内外的任意一个人,所以第一个人在排列中的位置一定在被删除之后,所以我们仍需要
但是当 \(l=1,S_1=L\) 时,包含 \(1\) 的合法区间一定形如 \(L\dots L\),此时 \(1\) 一定被第一个删除,且 \(1\) 可以攻击外部,所以 \(g_{1,i}=g_{1,i}+1\)
当 \(r=n,S_n=R\) 时同理。
那么我们最后的任务是合并这若干个合法区间,设 \(f_{i,j}\) 表示已经合并到了 \(i\) 号位置,当前有 \(j\) 个区间。因为每个区间有且仅有一人存活,所以答案即为 \(f_{n,j}\)。
\(f\) 的转移是容易的。