提示:
1. 这是一个dp题 , 不要妄想用bfs来写此题 , 样例都过不了
2. dp方程的含义: d [ i ] [ j ] , 用一个大写字母(i+'A') 扩展成长度为j的字典序最小的字符串(不含大写字母)
此处请思考些时间 , 怎么转移状态;
3. 下面是我自己的转移方法 , 与紫书上的不同 , 紫书上把边拆分成了很多块 , 但对于初学做这个题的人来说 , 把边颠过来倒过去就够呛了 , 所以我的解法在保证时间的情况下尽量去降低代码和理解的难度:
下文中所有的状态指d[i][j] , 所有的边指的是原题中形如"A=Sbs.."的文法
首先考虑转移方程:(分成同层和非同层两个部分)
对于d [ i ] [ j ] ,遍历 i 的每一条边 , 尝试通过这些边来从非同层的状态转移(有一点抽象 , 想象把一个字符串中的所有大写字母换成另一字符串 , 并拼接在一起) , 这就是我们要做的事情 ,类似于每一个大写字母贡献一个长度 , 然后小写字母呆在原来的位置, 至于非同层状态是指大写字母贡献的那个长度要严格小于 j (即是现在计算的长度)
同层dp , 就是一个dijktra 算法 , 因为在同一层中d值我们只用较小的状态去更新较大的状态 , 与dijkstra的思想不谋而合
如果能够同层dp , i 肯定有这样一些转换边 , 转换出来的字符串都是大写字母 , 我们从中选择一个大写字母来p , 用d[p][j]来更新 d[i][j] , 当然除了p以