题解 [USACO19JAN]Cow Poetry G

怎么洛谷题解区说这题的 dp 很 navie 啊,我根本不会……

\(n\) 个词,第 \(i\) 个长度为 \(l_i\),韵母为 \(y_i\),每行长度为 \(k\),要求一些行要押韵,求方案数。

开始想的是做一个背包,求出每个长度有多少种方案然后在怎么怎么搞一下,可是发现搞不出来。

太死板了!这题要前几个多少长度有何用?我关心的是结尾的韵母是什么啊!
所以改变一下状态,\(f_{i, j}\) 表示长度为 \(i\) 的结尾是 \(j\) 的方案数。如果能把这个快速得到,那么对于每一个押韵的方案,只要把这个的出现次数次都加起来就可以了。

大概想一想方程是怎样的。如 \(f_{i, j} = \sum_{y_k = j}\sum_{l=1}^s f_{i-l_k, l}\),但是这玩意儿看上去时间复杂度有四次,而且又没有形似“前 \(i\) 个”这样的状态,怎么转移啊。
先考虑一下怎么转移。这个 dp 转移的方向是从 \(i\) 小的到 \(i\) 大的,而且后面一个 \(\Sigma\) 是从 \(1\) 开始的所有,我们按照长度来转移肯定是没有问题的。
时间复杂度上状态确实有 \(n^2\),但转移中颜色只会出现一次,加起来是 \(n\) 的,那么总共就是 \(n^2k\) 了,没有办法接受。

后面既然都从 \(1\) 开始了,那么就是一个显然的前缀和优化了。令 \(g_i = \sum_{j=1}^s f_{i, j}\) 就可以了。
具体实现的时候,可以不用把每个颜色分开,枚举长度后直接枚举每一个词,然后用它的 \(y\) 更新 \(f\),并在 \(g\) 中加上相应的贡献就可以了。

posted @ 2021-07-27 09:13  Acfboy  阅读(55)  评论(0)    收藏  举报