给一个字符串, 求它的子串有多少个回文串, 就是可以不连续的那种。 两种情况视为不同, 只要有一个字符在原串的位置不同就可以, 及时两个子串相同。
区间dp, dp[l][r] = dp[l+1][r]+dp[l][r-1]-dp[l+1][r-1]。 如果s[l] == s[r] , dp[l][r] += dp[l+1][r-1]+1。
我写的记忆化搜索用C++才可以过 G++会T....
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; const int mod = 10007; int dp[1005][1005]; char s[1005]; int dfs(int l, int r) { if(l>r) { return dp[l][r] = 0; } if(~dp[l][r]) return dp[l][r]; if(l == r) return dp[l][r] = 1; dp[l][r] = (dfs(l+1, r) + dfs(l, r-1) - dfs(l+1, r-1) + mod)%mod; if(s[l] == s[r]) dp[l][r] = (dp[l][r] + dp[l+1][r-1] + 1 + mod)%mod; return dp[l][r]; } int main() { int n; scanf("%d", &n); for(int i = 1; i<=n; i++) { scanf("%s", s); int len = strlen(s); memset(dp, -1, sizeof(dp)); printf("Case %d: %d ", i, dfs(0, len-1)); } return 0; }