CF1327F AND Segments
作者:互联网
CF1327F AND Segments
Solution
原问题可以拆位分成 \(k\) 个子问题,答案为每个问题的方案数之积。
这些子问题均为:给定 \(m\) 个区间,要求这些区间的与值为 \(0\) 或 \(1\)。
区间赋值用差分解决。
对于限制为 \(1\) 的区间,其中的数都要填 \(1\)。对于限制为 \(0\) 的区间,问题要棘手一些。
那么我们以 \(0\) 为中心,考虑 \(0\) 放在什么位置的方案数是多少。
记 \(pos[i]\) 为 \(i\) 之前(不包括 \(i\))最后一个 \(0\) 至少应该放在什么位置。
这个数组预处理需要注意的是,当 \(i\) 在限制为 \(0\) 的区间内时,\(pos[i]\) 并不是这个区间的左端点,因为我可以在 \(i\) 的右侧的该区间范围内放置 \(0\)。
记 \(f[i][j]\) 表示考虑前 \(i\) 个数,最后一个 \(0\) 放在 \(j\) 的方案数。
当 \(j < pos[i]\) 时,由 \(pos\) 的定义,\([1, pos[i]]\) 内的数都应该填 \(1\),产生矛盾,因此没有方案。
当 \(pos[i] \le j < i\) 时,\(f[i][j] = f[i - 1][j]\)。
当 \(i = j\) 时,如果当前位必须填 \(1\),\(f[i][j] = 0\)。否则,\(f[i][j] = \sum\limits_{k=pos[i]}^{i - 1}f[i - 1][k]\)。
我们发现第一维可以省掉。转化 dp 数组的意义:直接记 \(f[i]\) 表示最后一个 \(0\) 填 \(i\) 的方案数。
第二种情况可以忽略;而第一,三种情况是紧密联系在一起的,可以维护这样一个 \(f\) 的和 \(sum\),不断移动 \(l = pos[i]\)。\(l\) 随 \(i\) 单调不减。
当 \(l\) 向右移,\(sum\) 就减去之前的 \(f\) 值;枚举并计算完当前新的 \(f\) 值,将它加入 \(sum\) 中。
时间复杂度和空间复杂度就都是 \(O(n)\) 的了。
总结一下,我们发现这种 dp 题都会把枚举考虑前 \(i\) 位给设出来,而这一位可以帮我们考虑更细节的 dp 转移关系,且这一维往往可以被省略掉。
以容易的条件为底板,以棘手的条件为中心进行问题解决。
标签:CF1327F,sum,pos,区间,Segments,dp 来源: https://www.cnblogs.com/Schucking-Sattin/p/16687232.html