Codeforces Round #556 (Div. 2)前(第)四题解析

Codeforces Round #556 (Div. 2)前四题解析

诗云:暮春三月,江南草长。杂花生树,群莺乱飞。
(然而五一回苏北。。。不过一样可以和几个挚友出去哈啤)

ABC

水。

D

难难难!
传送门:http://codeforces.com/contest/1150/problem/D
题解:这一题的dp不太好想,我也是看了官方tutorial才恍然大悟。
考虑这样一个dp(l1,l2,l3),表示在religion1,2,3长度分别为l1,l2,l3时,最右边一个被涂色的字母位置的最小值,如果不能实现则记为INF.那么对于每一个"+“操作,我们需要更新前面所有的最小值。
怎样更新呢?
显然可以知道,对于每一次更新,最重要的是怎么找到下一个要添加字符的位置,于是我们可以建一个next[maxn][30]的数组,用于查询每个位置每个字符下一次出现的位置,没有就记为INF。用从后往前推的方法可以在o(26n)的时间建立数组。
这时候我们用三个字符数组s1,s2,s3存religion1,2,3的字符串,就很容易得到状态转移方程:
dp[i][j][k]=min(next[dp[i-1][j][k]][s1[i]],next[dp[i][j-1][k]][s2[j]],next[dp[i][j][k-1]][s3[k]])
由于s1,s2,s3长度均不超过250,故每次”+"操作可在o( 25 0 2 250^2 2502)时间内完成。于是总体时间复杂度:o(q* 25 0 2 250^2 2502)
要注意的是这题初始化比较麻烦,我因为这个浪费了20分钟调代码!!!
AC代码(似乎写得太烦了):https://xlorpaste.cn/0AD8Fg
(完)

你可能感兴趣的:(dp)