1 /*
2 将字符串逆序,找出原字符串与该字符串的公共子序列,则其余部分为需要添加的字符
3 状态转移方程参考最长公共子字符串
4 http://www.cnblogs.com/qq188380780/p/6678471.html
5 */
6 #include<cstdio>
7 #include<cstring>
8 #define Max(a,b) ((a)>(b)?(a):(b))
9 char a[1005],b[1005];
10 int d[1005][1005];
11
12 void solven(int len)
13 {
14 int i,j;
15 for(i=1; i<=len; ++i)
16 {
17 for(j=1; j<=len; ++j)
18 {
19 if(a[i-1] == b[j-1])
20 d[i][j] = d[i-1][j-1] + 1;
21 else
22 d[i][j] = Max(d[i-1][j],d[i][j-1]);
23 }
24 }
25 }
26
27 int main()
28 {
29 int t,i,j,len;
30 scanf("%d",&t);
31 while(t--)
32 {
33 memset(d,0,sizeof d);
34 scanf("%s",a);
35 len = strlen(a);
36 for(i=0; i<len; ++i)
37 b[i] = a[len-1-i];
38 solven(len);
39 printf("%d\n",len-d[len][len]);
40 }
41 return 0;
42 }
43
44 //空间优化,与最长公共子序列一样
45 #include<cstdio>
46 #include<cstring>
47
48 char a[1005],b[1005];
49 int d[1005];
50
51 void solven(int len)
52 {
53 int i,j,t,temp;
54 for(i=0; i<len; ++i)
55 {
56 for(j=t=0; j<len; ++j)
57 {
58 temp = d[j];
59 if(a[i] == b[j])
60 d[j] = t + 1;
61 else if(d[j] < d[j-1])
62 d[j] = d[j-1];
63 t = temp;
64 }
65 }
66 }
67
68 int main()
69 {
70 int t,i,j,len;
71 scanf("%d",&t);
72 while(t--)
73 {
74 memset(d,0,sizeof d);
75 scanf("%s",a);
76 len = strlen(a);
77 for(i=0; i<len; ++i)
78 b[i] = a[len-1-i];
79 solven(len);
80 printf("%d\n",len-d[len-1]);
81 }
82 return 0;
83 }
84
85 //另可不必再开数组存逆序,只需要记录位置即可
86 #include<cstdio>
87 #include<cstring>
88
89 char a[1005];
90 int d[1005];
91
92 void solven(int len)
93 {
94 int i,j,t,temp;
95 for(i=0; i<len; ++i)
96 {
97 for(j=t=0; j<len; ++j)
98 {
99 temp = d[j];
100 if(a[i] == a[len-1-j])
101 d[j] = t + 1;
102 else if(d[j] < d[j-1])
103 d[j] = d[j-1];
104 t = temp;
105 }
106 }
107 }
108
109 int main()
110 {
111 int t,i,j,len;
112 scanf("%d",&t);
113 while(t--)
114 {
115 memset(d,0,sizeof d);
116 scanf("%s",a);
117 len = strlen(a);
118 for(i=0; i<len; ++i)
119 b[i] = a[len-1-i];
120 solven(len);
121 printf("%d\n",len-d[len-1]);
122 }
123 return 0;
124 }