P6883 [COCI2016-2017#3] Kroničan
\(\text{solution}\)
个人认为有些地方还是比较妙的。
首先看到 \(n \le 20\) 就知道了这道题是一道状压 DP,考虑怎么状压:
设 \(f_i\) 为当前状态为 \(i\) 时的最小代价,此时 \(0\) 表示有水,\(1\) 表示没水。
然后我们考虑这道题的状态转移方程是:
\[f_{i} = \min(f_{i \& (1 << j)} + c_{j + 1, l + 1})
\]
此时我们的 \(j\) 从 \(0\) 开始循环(因为二进制是从 \(0\) 位开始的)且 \(j\) 位为 \(1\),\(k\) 位为 \(0\)。
接下来我们考虑一个问题,如何证明这个 DP 状态是已经被求解过的:
考虑 \(i \& (1 << j)\) 肯定是把某一位变为 \(0\),也就是从有水到没水,就是 \(j\) 倒水倒到 \(k\) 里,这个二进制数肯定比当前二进制数小,所以肯定被求解过(这就是为什么有水为 \(0\),无水为 \(1\))。

浙公网安备 33010602011771号