矩阵上的 dp:
按格 dp / 轮廓线 dp
设 \(f[i,j,S]\) 表示考虑到第 \(i\) 行第 \(j\) 个格子,轮廓线上所有的格子的状态。
复杂度为 \(\Theta(nm|S|)\)。
按行 dp
\(f[i,S]\) 表示选完前 \(i\) 行的合法方案数。
总复杂度为 \(\Theta(n|S|^2)\)。
P3226 [HNOI2012] 集合选数
给定集合 \(S=\{1,2,\cdots,n\}\)。求满足以下条件的 \(T\) 的个数。
- \(T\subseteq S\);
- 若 \(i\in S\),则 \(2i,3i\notin S\)。
\(n\leq 10^5\)。
设 \(f[i,j,S]\) 表示考虑到第 \(i\) 行第 \(j\) 个格子,轮廓线上所有的格子的状态。
[ABC328G] Cut and Reorder
菜。
给定两个长度为 \(n\) 的序列 \(a,b\) 和一个正整数 \(c\),有两种操作。
- 把 \(a\) 分成任意 \(x\) 个子段,任意重排后,组成新的 \(a\) 序列。代价为 \(c\cdot (x-1)\)。
- 把 \(a_i\) 加上 \(x\)(\(x\) 为任意整数)代价是 \(|x|\)。
问把 \(a\) 变成 \(b\) 的最小代价。
不难发现操作 \(1\) 只会用一次。于是问题转化为:
记 \(b_i\) 匹配了 \(a_{p_i}\)。最小化 \(\sum|a_{p_i}-b_i|\) 与 \(p_i\) 的段数。
其中 \(p_i\) 是一个排列,段定义为极长的区间 \([l,r]\),使得 \(\forall i\in [l,r)\),有 \(p_i=p_{i+1}-1\)。