Source
IOI 2000
When I first saw this question, I couldn't figure out a good way to do it at the moment. I saw that classification was in dynamic planning, and I thought about it in this regard. I looked at other people's ideas, suddenly, I turned back the given string, and then joined the original string to find their longest public sequence, and then took the length of the string minus the length of their longest public sequence, the result is the minimum number of characters to be added. If you think of this place, this question can be easily solved. If you use LIC directly, the state equation is the same as the previous question;
# Include <cstdio> # include <cstring> # define max (A, B) A> B? A: bconst int maxn = 1001; char a [maxn], B [maxn]; int DP [maxn] [maxn]; // set the DP type to char type last night, and submit it for WA and screen flushing... No !! Int main () {int N, I, j, Len; scanf ("% d", & N); While (n --) {memset (A, 0, sizeof (a); memset (DP, 0, sizeof (DP); scanf ("% s", a); Len = strlen (); for (I = len-1, j = 0; I> = 0; I --) B [J ++] = A [I]; for (I = 1; I <= Len; I ++) {for (j = 1; j <= Len; j ++) {if (a [I-1] = B [J-1]) DP [I] [J] = DP [I-1] [J-1] + 1; // recursive relationship else DP [I] [J] = max (DP [I-1] [J], DP [I] [J-1]);} printf ("% d \ n", len-DP [Len] [Len]);}
Seeing what others have written is another way of thinking. It is also a dynamic planning, but the recurrence relationship is a little different;
This eliminates the need for reverse engineering;
#include<stdio.h> #include<string.h> int f[1005][1005]; int main() { int n; scanf("%d",&n); while (n--) { char s[1005]; scanf("%s",s); int k,i,j,l=strlen(s); for (i=0;i<l;++i) f[i][i]=0; for (k=2;k<=l;++k) { for (i=0;i<=l-k;++i) { int p=i+k-1; if (s[i]==s[p]) { f[i][p]=f[i+1][p-1]; } else { f[i][p]=1+(f[i][p-1]<f[i+1][p]?f[i][p-1]:f[i+1][p]); } } } printf("%d\n",f[0][l-1]); memset(f,0,sizeof(f)); } return 0; }
Seeing the optimal code of others, the memory usage is very small and worth learning. There is also a scrolling array that seems to save memory and has not been touched;
#include<stdio.h>#include<string.h>using namespace std;int m[1000],i,j,t1,t2,len;char s[1001];int main() { int N; scanf("%d",&N); while(N--){ scanf("%s",s); len=strlen(s); for(i=len-1;i>=0;i--){ m[i]=0; t1=m[i]; for(j=i+1;j<len;j++){ t2=m[j]; if(s[i]==s[j]) m[j]=t1; else m[j]=m[j-1]<m[j]?m[j-1]+1:m[j]+1; t1=t2; } } printf("%d\n",m[len-1]); }}