Time Limit:3000MS | Memory Limit:65536K | |
Total Submissions:48933 | Accepted:16817 |
Description
As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome.
Input
Output
Sample Input
5 Ab3bd
Sample Output
2
#include<iostream>
using namespace std;
#define NUMMAX 5001
short int getLCS(char s1[],char s2[],int len1,int len2);
short int dp[NUMMAX][NUMMAX];
int main(){
int N;
cin>>N;
char s1[NUMMAX],s2[NUMMAX];
for(int i=1;i<=N;i++){
cin>>s1[i];
s2[N-i+1]=s1[i];
}
cout<<N-getLCS(s1,s2,N,N);
system("pause");
}
short int max(int a,int b){
return a>b?a:b;
}
short int getLCS(char s1[],char s2[],int len1,int len2){
for(int i=0;i<=len2;i++)
dp[0][i]=0;
for(int i=0;i<=len1;i++)
dp[i][0]=0;
for(int i=1;i<=len1;i++){
for(int j=1;j<=len2;j++){
if(s1[i]==s2[j]){
dp[i][j]=max((dp[i-1][j-1]+1),dp[i][j]);
}else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[len1][len2];
}
解题报告copy之:
题意:
给你一串字符串,让你求最少加入几个字符,才能使得这个字符串是个回文串。
做法:
设a[i]是这个字符串,b[i]是这个字符串的逆序串。
那么a[i],b[i]的最长公共子序列就是所求的字符串里拥有的最大的回文串。
然后用总串长减去最大的回文串长度即为所求。
求最长公共子序列的公式为:
dp[i][j]=max(dp[i-1] [j],dp[i][j-1])
if(a[i]==b[i])
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
如果直接求的话,势必要开一个5001*5001的数组,铁定MLE。
有一下两种解决方法:
1,开short int型数组
这是poj返回的结果:
2,运用动态数组。
根据dp滚动的过程我们可以知道,dp【i】【j】的值不会与dp[i-2][0.....n]的值有关系。
那么可以把dp[i][j]的值覆盖到dp[i-2][j]上。即dp[i][j]为dp[i%2][j];
poj返回的结果:
对比以上两种方法,显而易见的可以得出2的方法很节约空间,就是耗时略长。
1,short int数组
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- #definemax(a,b)(a>b?a:b)
- usingnamespacestd;
- shortintdp[5001][5001];
- intmain()
- {
- inta[5001];
- intb[5001];
- inti,j;
- intn;
- charstr;
- cin>>n;
- getchar();
- for(i=1;i<=n;i++)
- {
- scanf("%c",&str);
- a[i]=str;
- b[n-i+1]=str;
- }
- for(i=0;i<=n;i++)
- {
- dp[i][0]=0;
- dp[0][i]=0;
- }
- for(i=1;i<=n;i++)
- {
- for(j=1;j<=n;j++)
- {
- dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
- if(a[i]==b[j])
- {
- dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
- }
- }
- }
- intlen;
- len=dp[n][n];
- printf("%d\n",n-len);
- return0;
- }
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- usingnamespacestd;
- intmain()
- {
- inta[5001];
- intb[5001];
- intdp[10][5001];
- inti,j;
- intn;
- charstr;
- cin>>n;
- getchar();
- for(i=1;i<=n;i++)
- {
- scanf("%c",&str);
- a[i]=str;
- b[n-i+1]=str;
- }
- dp[1][0]=dp[0][0]=0;
- for(i=0;i<=n;i++)
- {
- dp[0][i]=0;
- }
- for(i=1;i<=n;i++)
- {
- for(j=1;j<=n;j++)
- {
- dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]);
- if(a[i]==b[j])
- {
- dp[i%2][j]=max(dp[i%2][j],dp[(i-1)%2][j-1]+1);
- }
- }
- }
- intlen;
- len=dp[n%2][n];
- printf("%d\n",n-len);
- return0;
- }
题意:
给你一串字符串,让你求最少加入几个字符,才能使得这个字符串是个回文串。
做法:
设a[i]是这个字符串,b[i]是这个字符串的逆序串。
那么a[i],b[i]的最长公共子序列就是所求的字符串里拥有的最大的回文串。
然后用总串长减去最大的回文串长度即为所求。
求最长公共子序列的公式为:
dp[i][j]=max(dp[i-1] [j],dp[i][j-1])
if(a[i]==b[i])
dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
如果直接求的话,势必要开一个5001*5001的数组,铁定MLE。
有一下两种解决方法:
1,开short int型数组
这是poj返回的结果:
2,运用动态数组。
根据dp滚动的过程我们可以知道,dp【i】【j】的值不会与dp[i-2][0.....n]的值有关系。
那么可以把dp[i][j]的值覆盖到dp[i-2][j]上。即dp[i][j]为dp[i%2][j];
poj返回的结果:
对比以上两种方法,显而易见的可以得出2的方法很节约空间,就是耗时略长。
1,short int数组
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- #definemax(a,b)(a>b?a:b)
- usingnamespacestd;
- shortintdp[5001][5001];
- intmain()
- {
- inta[5001];
- intb[5001];
- inti,j;
- intn;
- charstr;
- cin>>n;
- getchar();
- for(i=1;i<=n;i++)
- {
- scanf("%c",&str);
- a[i]=str;
- b[n-i+1]=str;
- }
- for(i=0;i<=n;i++)
- {
- dp[i][0]=0;
- dp[0][i]=0;
- }
- for(i=1;i<=n;i++)
- {
- for(j=1;j<=n;j++)
- {
- dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
- if(a[i]==b[j])
- {
- dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
- }
- }
- }
- intlen;
- len=dp[n][n];
- printf("%d\n",n-len);
- return0;
- }
- #include<iostream>
- #include<stdio.h>
- #include<string.h>
- usingnamespacestd;
- intmain()
- {
- inta[5001];
- intb[5001];
- intdp[10][5001];
- inti,j;
- intn;
- charstr;
- cin>>n;
- getchar();
- for(i=1;i<=n;i++)
- {
- scanf("%c",&str);
- a[i]=str;
- b[n-i+1]=str;
- }
- dp[1][0]=dp[0][0]=0;
- for(i=0;i<=n;i++)
- {
- dp[0][i]=0;
- }
- for(i=1;i<=n;i++)
- {
- for(j=1;j<=n;j++)
- {
- dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]);
- if(a[i]==b[j])
- {
- dp[i%2][j]=max(dp[i%2][j],dp[(i-1)%2][j-1]+1);
- }
- }
- }
- intlen;
- len=dp[n%2][n];
- printf("%d\n",n-len);
- return0;
- }