Description
爱美之心人皆有之,GG也不例外。所以GG他对于完美串有一种热衷的爱。在GG眼中完美串是一个具有无比魅力的01子串。这个子串有之其魅力之处,对它取反后水平翻转,它又和它原来的一模一样。这就是GG热爱它的原因。但是世上并不是所有的01串都是完美串,所以GG下定决心想改造01串,使所有的01串都成为完美串。但是改造01串是一个巨大的工程,GG太忙了,他还差T个01串未改造,他需要你的帮助。而你只需要告诉它至少添加几个'0','1'字符就可以使得01串成为完美串。
Input
有T组数据输入。(T<=100)
每组数据只有两行,第一行一个正整数n(1<=n<=1000),接下来一行是一个01字符串,长度为n。
Output
对于每组数据输出一行结果
Sample Input
2
4
1001
3
111
Sample Output
2
3
HINT
大意:判断最长公共子串然后总的减去就是,因为最长的匹配了就不动了,因为只要剩下的其中一组有了数匹配剩下一组也匹配完了,具体弄几组数据就知道,对称的。
然后就最长子串算法一算就行。
法一:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; char s[1100]; int dp[1100][1100]; int a[1100],b[1100]; int main() { int n,T; scanf("%d",&T); while(T--){ scanf("%d",&n); scanf("%s",s); int k = n - 1; for(int i = 0; i < n ;i++){ a[i] = s[i] - '0'; b[k--] =1 - a[i]; } memset(dp,0,sizeof(dp)); for(int i = 0; i < n ; i++){ for(int j = 0; j < n ; j++){ if(a[i] == b[j]) dp[i+1][j+1] = dp[i][j]+1; else dp[i+1][j+1] = max(dp[i+1][j],dp[i][j+1]); } } printf("%d ",n-dp[n][n]); } return 0; }
法二:
用DP思想,dp[i][j]表示从i到j所需添加的最少的字符
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAX = 5005; int dp[MAX][MAX]; int main() { memset(dp,0,sizeof(dp)); int n; char s[MAX]; scanf("%d%s",&n,s); int i,j; for(i = n - 1; i >= 0;i--){ dp[i][i] =0; for( j = i + 1; j < n;j++){ if(s[i] == s[j]) dp[i][j] = dp[i+1][j-1]; else dp[i][j] =min(dp[i+1][j],dp[i][j-1])+1; } } printf("%d ",dp[0][n-1]); return 0; }