The topic is to calculate a string with a minimum of several characters to make it a palindrome.
More than a year ago, I LCS this classic DP example to see also smattering encountered the same problem, http://acm.fafu.edu.cn/problem.php?id=1007.
At that time completely on their own blind yy out the solution of LCS:
That's what I was thinking:
- Divide the string into two parts, assuming that these two parts belong to the new palindrome string symmetric two parts, then to add a minimum string to form a palindrome string will need the former part and the latter part of the public part of the most, that is, their (a positive and a reverse) LCS.
- This is the enumeration of the middle part of the position (in addition to discuss the odd and even palindrome string, the odd enumeration is the position of the middle element), and then calculate the length of the two parts -2*lcs (a positive and reverse), take the smallest.
- The length of the two-part (one-to-one counter) LCS can be preprocessed by calculating the original string and its inverse string of LCS, which is the meaning of dp[i][j]--s11...s1i and s21...s2j LCS.
I searched, really have LCS solution, but not the same is very simple is the length of-lcs is the solution. It's hard to imagine that I could have come up with this solution entirely by myself.
Now do this problem, think of the interval DP, and then engaged in the next AC, although the state transfer just by feeling to write, correctness smattering.
1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespacestd;5 #defineINF (1<<29)6 intd[222][222];7 Charstr[222];8 intMain () {9 intT;Tenscanf"%d",&t); One for(intCse=1; cse<=t; ++CSE) { Ascanf"%s", str); - intn=strlen (str); - for(intI=0; i<n; ++i) { the for(intj=i+1; j<n; ++J) d[i][j]=INF; - for(intj=0; j<=i; ++J) d[i][i]=0; - } - for(intlen=2; len<=n; ++Len) { + for(intI=0; i+len<=n; ++i) { - if(str[i]==str[i+len-1]) d[i][i+len-1]=d[i+1][i+len-2]; + Else{ A for(intJ=i; j<i+len-1; ++J) d[i][i+len-1]=min (d[i][i+len-1],d[i][j]+i+len-1-j); at for(intj=i+len-1; j>i; --J) d[i][i+len-1]=min (d[i][i+len-1],d[j][i+len-1]+j-i); - } - } - } -printf"Case %d:%d\n", cse,d[0][n-1]); - } in return 0; -}
LightOJ1033 generating Palindromes (interval Dp/lcs)