加载中...

2025杭电多校8 1012(古怪dp)

1012

这道题个人感觉与平常的 \(dp\) 题目大有不同,不好想,遂记录。

简述题意:给定一个排列(\(n \leq 3000\)),每次操作可以选定一个区间,并将区间内所有数均变成区间最小值,可进行任意次操作,求可以形成的不同序列方案数。

若是依照常见的状态定义(考虑前 \(i\) 个数,blala..,序列方案数),会发现很难入手,故需另辟蹊径。

观察到一个性质:对于某个数 \(c\),它可能出现的位置一定是一段连续的子区间,且满足:

\[min_{l \leq i \leq r} a[] = c \]

而对不同最小值的操作顺序是可任选的,因此可以看作是对序列做如下变换:初始时序列内的每个位置均无任何数字(待填),每次可以任选某个位置,并将 该位置附近未赋值的位置 设置为 该位置上原来的数字(范围不能超过上述区间 \([l,r]\))。求可形成序列的方案数。

考虑状态定义: \(dp_{i,j}\):只考虑使用第 \(1 \backsim i\) 个数字操作,覆盖的前缀长度至少\(j\),形成序列 \(a[1 \backsim j]\) 的方案数。

状态转移:决策第 \(i\) 个数字是否参与操作,覆盖位置 \(1 \backsim j\) 上的某些区间。

  1. 不参与操作:即前 \(i-1\) 个数字覆盖位置 \(1 \backsim j\)

\[dp_{i,j} \leftarrow dp_{i-1,j} \]

  1. 参与操作,并覆盖 \(1 \backsim j\) 的某些位置:发现第 \(i\) 个位置在所有可操作位置的最右侧,分类讨论 \(i\)\(j\) 的大小关系:
  • \(i > j\):若对第 \(i\) 个数操作,欲覆盖位置 \(1 \backsim j\),则至少会覆盖到位置 \(j\),且须满足条件 \(j \in [l_{i},r_{i}]\)。故转移为:

\[dp_{i,j} \leftarrow dp_{i,j-1} \times [l_{i} \leq j \leq r_{i}] \]

  • \(i < j\): 若使用 \(a[i]\) 覆盖到的区间未达到位置 \(j\),则一定是对前 \(i - 1\) 个数的操作覆盖到了位置 \(j\),这种情况与 \(a[i]\) 不参与操作是等价的;否则,对 \(a[i]\) 的操作一定会覆盖到位置 \(j\),此时转移便与上面的转移相同。

具体细节见代码。

\(feeling:\) 感觉这道题对于蒟蒻来说十分困难,想了很长时间才弄懂个一知半解,甚至还不清楚用这个思路解释是否可行。看来还是题做少了qwq。。。

code

posted @ 2025-08-14 18:51  jxs123  阅读(16)  评论(0)    收藏  举报