#include<stdio.h> #include<iostream> #include<vector> #include<string> using namespace std; int f[1010][1010] = {0}; int main() { string s; getline(cin,s); int ans = 1; for(int i=0,tmp = s.length();i<tmp;i++){ f[i][i] = 1; if(i<tmp-1 && s[i] == s[i+1]){ f[i][i+1] = 1; ans = 2; } } for(int L = 3,tmp = s.length();L<=tmp;L++){ for(int i = 0;i+L-1<tmp;i++){ int j = i + L -1; if(s[i] == s[i+L-1] && f[i+1][j-1] == 1){ f[i][j] = 1; ans = L; } } } printf("%d",ans); return 0; }
题目大意:求一串字符串中的最长回文子串;
总结:
动态规划未必要在最后通过数组右下角的值确定,可以在求解的过程中更新,数组的最有用于保存之前递推的状态,相比直接暴力枚举节省了重复判断的时间
di 表示从i到j的子串是否是回文串 是 1,不是 0;
1. 递推方程: s[i] == s[j] di = di+1;
s[i] != s[j] di = 0;
2.边界(需要预处理) ;di =1; di = s[i] == s[i+1]?1:0;
i,j 如果从小到大顺序枚举,无法保证在更新di时,di+1已经被更新过了,
考虑枚举子串的起点和子串的长度,后面的状态长度为3.4...由前面的结果长度为1,2...更新
3.注意长度和下标的表示