HDU 3068 http://acm.hdu.edu.cn/showproblem.php?pid=3068
HDU 3294http://acm.hdu.edu.cn/showproblem.php?pid=3294
感觉DP相对实现起来更简洁一些,很容易想到,可以用bool dp[i][j]:表示从i到j是否为回文串,然后最长长度用一个变量记录就好
如果dp[i][j]为回文串,那么dp[i+1][j-1]必为回文串且s[i]==s[j],所以可以得到递推关系
if(dp[i+1]][j-1]&&s[i]==s[j]) dp[i][j]=1; maxlen=max(maxlen,i-j+1);
但是上述判断条件并不对……上面的条件漏掉了一个单个字符必为回文串的情况,第二个判断条件再加一个||j-i<2即可,或者最开始初始化dp数组的时候把i==j的部分赋值为true;
模板模板↓↓↓
bool dp[n][n]; string s; int n; int DP()
{ memset(dp, 0, sizeof(dp)); int maxlen = 0; for (int j = 0; j < s.length(); j++) for (int i = j; i >= 0; i--) if(s[i]==s[j]&&(j-i<2|| dp[i + 1][j - 1])) { dp[i][j] = 1; maxlen = max(maxlen, j - i + 1); } return maxlen; }
但是……dp数组这样开就太大了……相对短一些的字符串还能用,长的就不行了……
manacher
不会manacher的话,可以参考这个:https://segmentfault.com/a/1190000003914228#articleHeader8
HDU 3086
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAX = 110000 + 10; char s[MAX*2];//数组要开两倍的 int rl[MAX*2]; int n,pos,maxlen,maxright; int manacher() { for (int i = n; i >= 0; i--) { s[2 * i + 2] = s[i]; s[2 * i + 1] = '#'; } s[0] = '*'; s[n * 2 + 2] = '