P6275 [USACO20OPEN]Sprinklers 2: Return of the Alfalfa P 题解

一道很妙的 DP 题,一眼过去感觉这好像是个轮廓线 DP,然后这道题确实是轮廓线 DP 但不是 2 n 2^n 2n 那种的。

本篇题解参照了其他题解的思路 (我从来没写过这种套路的题),在此表示感谢。

直接进入正解。

首先规定一下本文中的 ( i , j ) (i,j) (i,j) 不是指第 i i i 行第 j j j 列,而是指网格线的第 i i i 行第 j j j 列这个点,如下图所示:

在这里插入图片描述
红色点就是 ( 4 , 5 ) (4,5) (4,5)

这道题的轮廓线就是从 ( 0 , 0 ) (0,0) (0,0) ( n , n ) (n,n) (n,n) 的一条往右下线。

f i , j , 0 / 1 f_{i,j,0/1} fi,j,0/1 表示前面 i i i 行都全部覆盖,当前轮廓线终止在 ( i , j ) (i,j) (i,j),轮廓线的最后一根方向是往右还是往下时的方案数。


首先看几个结论:

  1. 轮廓线的拐点数就是必须要放的洒水器数。

比如说下图,有 5 个拐点,那么就要放 5 个洒水器。

在这里插入图片描述

  1. 假设上图必须要放 k k k 个洒水器,整张图能放洒水器的面积为 S S S,那么对于当前轮廓线的总方案数为 2 S − k 2^{S-k} 2Sk
    这个结论还是很明显的吧,就是因为剩下的点可放可不放,而且每个点能放的洒水器数量只有一种。

好的又设 s u m i sum_{i} sumi 表示这一行的能放洒水器的数量(空地数),可以开始推方程了。

对于 f i , j , 0 f_{i,j,0} fi,j,0

我们发现其需要从 f i , j − 1 , 0 / 1 f_{i,j-1,0/1} fi,j1,0/1 转移。

  1. f i , j − 1 , 0 f_{i,j-1,0} fi,j1,0 转移。

此时是这样的:

在这里插入图片描述
发现拐点数没变,覆盖总面积也没变,因此 f i , j − 1 , 0 f_{i,j-1,0} fi,j1,0 的贡献是 f i , j − 1 , 0 f_{i,j-1,0} fi,j1,0

  1. f i , j − 1 , 1 f_{i,j-1,1} fi,j1,1 转移。

在这里插入图片描述

发现新增了一个红色的洒水器,总面积没变,对应的 2 S − k 2^{S-k} 2Sk 变为 2 S − k − 1 2^{S-k-1} 2Sk1,因此 f i , j − 1 , 1 f_{i,j-1,1} fi,j1,1 的贡献是 f i , j − 1 , 1 2 \dfrac{f_{i,j-1,1}}{2} 2fi,j1,1

综上, f i , j , 0 = f i , j − 1 , 0 + f i , j − 1 , 1 2 f_{i,j,0}=f_{i,j-1,0}+\dfrac{f_{i,j-1,1}}{2} fi,j,0=fi,j1,0+2fi,j1,1

对于 f i , j , 1 f_{i,j,1} fi,j,1

注意 f i , j , 1 f_{i,j,1} fi,j,1 需要从 f i − 1 , j , 0 / 1 f_{i-1,j,0/1} fi1,j,0/1 转移过来,因此面积数和拐点数都有变动。

f i − 1 , j , 0 f_{i-1,j,0} fi1,j,0 的贡献:面积数增加 s u m i sum_i sumi,拐点数增加 1,方案数变化为 2 S − k → 2 S − k + s u m i − 1 2^{S-k} \to 2^{S-k+sum_i-1} 2Sk2Sk+sumi1,因此贡献是 f i − 1 , j , 0 × 2 s u m i − 1 f_{i-1,j,0} \times 2^{sum_i-1} fi1,j,0×2sumi1

f i − 1 , j , 1 f_{i-1,j,1} fi1,j,1 的贡献:面积数增加 s u m i sum_i sumi,拐点数不变,方案数变化为 2 S − k → 2 S − k + s u m i 2^{S-k} \to 2^{S-k+sum_i} 2Sk2Sk+sumi,因此贡献是 f i − 1 , j , 1 × 2 s u m i f_{i-1,j,1} \times 2^{sum_i} fi1,j,1×2sumi

所以 f i , j , 1 = f i − 1 , j , 0 × 2 s u m i − 1 + f i − 1 , j , 1 × 2 s u m i f_{i,j,1}=f_{i-1,j,0} \times 2^{sum_i-1}+f_{i-1,j,1} \times 2^{sum_i} fi,j,1=fi1,j,0×2sumi1+fi1,j,1×2sumi

这一组转移可以参考下面两幅图:

在这里插入图片描述
在这里插入图片描述
注意 DP 的时候 i : 0 → n , j : 0 → n i : \text\red{0} \to n,j : \text\red{0} \to n i:0n,j:0n,整体代码还是很好写的。

Code:GitHub CodeBase-of-Plozia P6275 [USACO20OPEN]Sprinklers 2 Return of the Alfalfa P.cpp

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值