J题题解(ICPC Mid-Central USA Region 2019)

题意

请你统计所有满足m个约束的、长度为n的01序列的方案数。
约束会以如下形式给出:(1)l,r,"same"表示要求从下标l到下标r的01序列的值完全相同(全为0或全为1);(2)l,r,"different"表示要求从下标l到下标r的01序列的值不完全相同

解法

DP。

什么线索可以想到DP?

  • n的范围为5000,可以O(n^2);m的范围1e6,除了读入感觉很难再对m做文章。
  • 这是个统计方案的数数题,且不要求知道具体有哪些01序列,一般可用DP解。

突破口在哪里?

在约束条件那里。

  • “l,r,same”等价于从l到r染成同一种数字,因此跟r有关的状态看起来可以从l-1有关的状态那里转移过来(因为l到r都是同一种数字,可以把这个区间视为一个整体(或干脆就视为一个数字),这不会影响方案数)
  • “l,r,different”似乎比较难处理,因为我们并不知道“不完全相同”这个条件怎么利用,其实这个条件是对same的约束条件的某种约束,不妨在后面尝试推导DP的过程中思考怎么运用。

如何建立DP的状态和转移

我们可以直接考虑O(n^2)的二维数组的DP,因为这个是允许通过的标准姿势。
设置状态

我们定义dp[i][j],表示现在枚举到第i位,且从第j位到第i位都是同一个数字,并且第j位和第j-1位不是同一个数字的方案数。为什么要这样设置?这是出于方便统计答案的考量。这样设置状态不难发现最终答案为



一般在敲定DP状态后,我们就可以直接思考转移方式。如果能推出来这道题就做完了,如果不能那么可以再尝试设置新的DP状态。好消息是这题情况属于前者。

建立转移

首先,根据DP状态的定义,我们有初始状态 dp[1][1]=2,这是因为第一位没有约束,总可以取0或取1.

我们先假设m=0,即没有任何same和different的约束。

  • 我们先考虑dp[i][j]怎么从上一位的dp[i-1][j]转移过来。这里j>=1&&j<=i-1
    可以写出转移



    这是因为根据我们的DP定义,第j位到第i位必须是同一个数字,所以说第i位和第i-1位也将会是同一个数字。我们上面提到过,他们的方案数是一样的,可以直接转移。
  • 我们再考虑dp[i][i]怎么转移过来,考虑它的定义:第i位和第i-1位不一样的所有方案数。转移方程为



    而对于第i位和第i-1位一样的情况,我们已经在之前的dp[i][j](j<i)的时候考虑到了。这样,对于没有约束条件的DP转移,我们就完成了。

下面我们考虑约束条件如何改变我们转移。

  • 假设现在有一个约束条件:下标k到下标i必须是the same,那么形如dp[i][1],dp[i][2],dp[i][3],...,dp[i][k]都是合法的转移,因为他们满足约束条件;但是dp[i][k+1],dp[i][k+2],...,dp[i][i]都是不合法的转移,因为他们不满足the same的约束条件。
  • 同样的,假设现在有一个约束条件:下标k到下标i必须是different,那么形如dp[i][k+1],dp[i][k+2],dp[i][k+3],...,dp[i][i]都是合法的转移,因为他们满足约束条件;但是dp[i][1],dp[i][2],...,dp[i][k]都是不合法的转移,因为他们不满足different的约束条件。
    综合上面分析,我们发现:约束条件通过改变我们DP转移的枚举范围来限制方案数。于是我们可以写出最终的转移方程如下:






    这里same[i]表示跟i相同的,最左边的那个下标,diff[i]表示跟i不完全相同的,最右边的那个下标。

最后我们再考虑一些无解的特殊情况,这道题就完成了。参考代码