动态规划训练(2)

动态规划训练(2)
[http://acm.hust.edu.cn/vjudge/contest/view.action?cid=100313#overview]

A - Partitioning by Palindromes
利用Mancher算法求出每个字符的回文半径(存在回文串奇数偶数的差别)于是得到递归式
F(i) = Min(F(j) | sj+1..j 是回文串)
注意:算出每个字符半径后,不代表回文串的半径为该长度,可能比该长度小,需要循环判断(我就死在这里一次)

B 在原来的图上找到一些dp的转移关系,然后注意i -> i是合法的状态转移,递归式写着比较复杂,但是理解起来很简单

C 以每个元素向左求最长下降子序列,向右做最长下降子序列,然后取其中的最小值与其他的元素打擂台,找出最大值。
这道题难点就是利用二分查找降低复杂度,就是对长度为i的子序列,存储使得长度为i的子序列最后一个元素最小的值为多少记录下来,然后二分查找,就能很快确定此时元素的最长子序列。

D刚开始觉得很难,但是注意字符串里只有小写字母,而且状态转移只和每个S子串前缀和后缀有关(思考之后可以只和后缀有关),于是对于每个S串只用记录其存在多少个不同的字符,每个字符是多少个,然后连接
F(i , ch)代表后缀为ch的第i个S串的最优结果
F(i + 1, ch) 从以下两种情况去最优值
1 i有ch1 后缀, i+1ch2前缀 : F(i + 1, ch3) = F(i, ch1) + cnt[i + 1] - 1)(对与子串只有一种字符的要特殊处理)
2 i的所有后缀,i +1都没有,简单相加

E求最长回文子串
求出长度很容易但求出字符串很难,所以可以建立一个结构体dp数组
包含以下两种装态
  string str
  int len
 相信大家看到这里就可以在原来的基础上进行状态转移了
 注意将子串翻转之后求出的最长公共子串不是答案,其子串的前半段是最优解,所以推荐就在原先的子串上进行DP

你可能感兴趣的:(C++)