$\newcommand{\O}{\mathrm{O}}$
文字列内の最長連続部分回文列を求めるアルゴリズム.
時間計算量: $\O (n^2)$ ($n$ は文字列の長さ)
int LPS(const string& s) { int n = (int)s.size(); vector<vector<int> > dp(n,vector<int>(n+1,0)); rep(i,n){ dp[i][i+1] = 1; } //iは部分文字列の長さ for(int i = 2; i <= n; i++){ rep(j,n-i+1){ int k = i + j; if(s[j] == s[k-1]){ dp[j][k] = dp[j+1][k-1] + 2; }else{ dp[j][k] = max(dp[j][k-1], dp[j+1][k]); } } } return dp[0][n]; // 最長部分回文列の出力 // string res; // int ni = 0, nj = n; // while(nj-ni > 1){ // if(s[ni] == s[nj-1]){ // res.push_back(s[ni]); // ni++,nj--; // }else{ // if(dp[ni][nj] == dp[ni][nj-1]){ // nj--; // }else{ // ni++; // } // } // } // if(nj-ni){ // string tmp = res; // res.push_back(s[ni]); // reverse(tmp.begin(),tmp.end()); // res += tmp; // }else{ // string tmp = res; // reverse(tmp.begin(),tmp.end()); // res += tmp; // } }
verify していません(verify 問題を知らない)