题意:给一个字符串,然后搜寻其可以构成回文的子串。(只关心如何找就行,没有其他特殊的操作)
1.动态规划,状态有三个 边界是哪个字符的回文。 左边的下标,右边的下标。
2.状态转移部分:对每个长度的字串进行分析1.由哪个字符组成的回文
2.当两端字符不相同时,回文串只能向里面去找。(对于里面的部分是可以由其他字符构成的回文组成的。)
3.最后对这几个字符所构成的回文串加和即可。(每一个字符,代表了一类回文串的个数)
class Solution {
public:
int countPalindromicSubsequences(string S) {
int n=S.size();
int mod=1e9+7;
vector<vector<vector<int>>> dp_ptr(4,vector<vector<int>>(n,vector<int>(n)));
auto& dp=dp_ptr;
for(int i=n-1;i>=0;--i){
for(int j=i;j<n;++j){
for(int k=0;k<4;++k){
char c='a'+k;
if(j==i){
if(S[i]==c)
dp[k][i][j]=1;
else
dp[k][i][j]=0;
}
else{
if(S[i]!=c) dp[k][i][j]=dp[k][i+1][j];
else if(S[j]!=c) dp[k][i][j]=dp[k][i][j-1];
else {
if(j==i+1) dp[k][i][j]=2;
else{
dp[k][i][j]=2;
for(int m=0;m<4;m++){
dp[k][i][j]+=dp[m][i+1][j-1];
dp[k][i][j]%=mod;
}
}
}
}
}
}
}
int ans=0;
for(int k=0;k<4;k++){
ans+=dp[k][0][n-1];
ans%=mod;
}
return ans;
}
};