南阳37
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 }