思路
因为n<=5000,n^2的复杂度可以接受。 题目等价于求n-s和s的逆串的最长公共子序列, dp[i][j],即可求出。 考虑到内存问题,状态转移只和前一个i有关,所以直接记录前面一个状态就行。
代码
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
const int maxn=1e4+7;
typedef long long ll;
int dp[2][maxn];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n;
while(scanf("%d",&n)!=EOF)
{
string s;
cin>>s;
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(s[i-1]==s[n-j])
{
dp[i&1][j]=dp[(i-1)&1][j-1]+1;
}
else
{
dp[i&1][j]=max(dp[(i-1)&1][j],dp[i&1][j-1]);
}
}
}
cout<<n-dp[n&1][n]<<endl;
}
return 0;
}