标签:
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 54047 | Accepted: 18672 |
Description
Input
Output
Sample Input
5 Ab3bd
Sample Output
2
大致题意:给定一个字符串,问最少插入多少字符,使该字符变成回文字符串。
思路:设原字符串序列为X,逆序列为Y,则最少需要补充的字母数=X的长度-X和Y的最长公共子序列的长度。这道题有意思的地方不是发现这个公式,而是对空间的压缩处理。出具范围达到了5000,若开静态数组用int肯定会超,当时用short就会过了。最好的办法就是用滚动数组。求LCS的状态转移方程为:d[i][j]=d[i-1][j]+d[i][j-1];上面的d[i][j]只依赖于d[i-1][j],d[i][j-1];运用滚动数组d[i%2][j]=d[(i-1)%2][j]+d[i%2][j-1];滚动数组d[i%2][j]=d[(i-1)%2][j]+d[i%2][j-1];滚动数组实际是一种节省空间的方法,在时间上没有优势。
1 #include<iostream> 2 #include<string.h> 3 #include<algorithm> 4 #include<cmath> 5 #include<sstream> 6 #include<vector> 7 using namespace std; 8 int dp[2][5005]; 9 int main() 10 { 11 string s1,s2; 12 int i,n,j; 13 while(cin>>n) 14 { 15 cin>>s1; 16 s2=s1; 17 reverse(s1.begin(),s1.end()); 18 memset(dp,0,sizeof(dp)); 19 for(i=1;i<=n;i++) 20 { 21 for(j=1;j<=n;j++) 22 { 23 dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]); 24 if(s1[i-1]==s2[j-1]) 25 { 26 int temp=dp[(i-1)%2][j-1]+1; 27 dp[i%2][j]=max(dp[i%2][j],temp); 28 } 29 } 30 } 31 cout<<n-dp[n%2][n]<<endl; 32 } 33 return 0; 34 }
标签:
原文地址:http://www.cnblogs.com/caterpillarofharvard/p/4226268.html