UVa 10617 Again palindrome (classic Palindrome range DP)
Test instructions
Given a string s, the deletion of s, so that the remaining substring is a palindrome string, ask at most how many kinds of this seed string.
Ideas:
When it comes to palindrome strings, the first thing to think about is definitely the interval DP, how to write the state transition equation?
Cut straight from test instructions: Dp[i, j] indicates the maximum number of such substrings in the interval [I, j].
1. s[i] = = S[j] Remove s[i], then a sub-problem is dp[i+1, j]; Remove S[j], another sub-problem is dp[i, j-1];
Obviously the two sub-problems overlap, the overlapping part is dp[i+1, j-1], so subtract this part.
If S[i], s[j] do not remove it? Because s[i] = = S[j], s[i] and s[j] make up a substring of the text string, and S[i],s[j] and dp[i+1, J-1]
All of the sub-strings contained inside the string are formed into a string of words, then the solution of this sub-problem is obviously dp[i+1, j-1] + 1.
So there will be dp[i][j] = Dp[i+1][j] + dp[i][j-1] + dp[i+1, j-1] + 1-dp[i+1, j-1];
Simplification for dp[i][j] = Dp[i+1][j] + dp[i][j-1] + 1;
2. s[i]! = S[j] At this time the sub-problem is simpler than the above, because S[i] s[j] and dp[i+1, J-1] The palindrome string does not constitute a palindrome.
So dp[i][j] = Dp[i+1][j] + dp[i][j-1]-dp[i+1][j-1];
<span style= "FONT-SIZE:18PX;" > #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include < string> #include <algorithm> #include <queue> #include <stack>using namespace std; #define LL Long Longconst Double PI = ACOs ( -1.0); const double e = 2.718281828459;const double eps = 1e-8;const int maxn = 65;ll dp[maxn][m Axn];char S[maxn];int Main () {//freopen ("In.txt", "R", stdin); Freopen ("OUT.txt", "w", stdout); int case; cin>>case; while (case--) {scanf ("%s", s+1); int len = strlen (s+1); memset (DP, 0, sizeof (DP)); for (int i = 1; I <= len; i++) {dp[i][i] = 1; } for (int k = 2; k <= Len; k++) {for (int i = 1, j = k; J <= Len; i++, J + +) { if (s[i] = = S[j]) dp[i][j] = dp[i+1][j]+dp[i][j-1]+1; else Dp[i][j] = dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]; }} cout<<dp[1][len]<<endl; } return 0;} </span>
The following is a recursive notation, a mnemonic search.
<span style= "FONT-SIZE:18PX;" > #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include < string> #include <algorithm> #include <queue> #include <stack>using namespace std; #define LL Long Long#define Max (A, B) (a) > (b)? (a):(B) Const double PI = ACOs ( -1.0); const double e = 2.718281828459;const double eps = 1e-8;const int maxn = 65;ll DP[MAXN ][maxn];char s[maxn];ll dfs (int l, int r) {if (Dp[l][r]! =-1) return dp[l][r]; if (l >= R) return dp[l][r] = (l==r)? 1:0; if (s[l] = = S[r]) dp[l][r] = max (Dp[l][r], DFS (l+1, R) +dfs (L, r-1) +1); else Dp[l][r] = max (Dp[l][r], DFS (l+1, R) +dfs (L, r-1)-dfs (l+1, r-1)); return dp[l][r];} int main () {//freopen ("In.txt", "R", stdin); Freopen ("OUT.txt", "w", stdout); int case; cin>>case; while (case--) {scanf ("%s", s+1); int len = strlen (s+1); Memset (DP,-1, sizeof (DP)); Dp[1][len] = DFS (1, Len); cout<<dp[1][len]<<endl; } return 0;} </span>
UVa 10617 Again palindrome (palindrome series interval DP)