您的位置:首页 > 其它

POJ-1159-Palindrome -dp

2015-11-12 16:19 513 查看
给一个长度为 5000的串

找出 最少插入多少个字符 得到一个回文串

思路1:

把该串和其逆序 求一遍 LCS.  答案就是len-lcs

思路2:

dp   

 

if (tm[i]==tm[j])
dp[i][j]=dp[(i+1)][j-1];
else
dp[i][j]=min(dp[(i+1)][j],dp[i][j-1])+1;


可用dfs或者for循环

由于内存太大,用dfs不好用上滚动数组。。。

dfs版本

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
int min(int a,int b)
{return a<b?a:b;}
int min(int a,int b,int c)
{
return min(c,min(a,b));}
char tm[5005];
int dp[5005][5005];
const int inf=1147483647;
int dfs(int i,int j)
{
if (i>j)
return 0;
if (i==j)
return 	dp[i][j]=0;

if (dp[i][j])
return dp[i][j];

if (tm[i]!=tm[j])
return dp[i][j]=min(dfs(i+1,j),dfs(i,j-1))+1;
else
return dp[i][j]= dfs(i+1,j-1);

}

int main()
{
int n;
cin>>n;
scanf("%s",tm);
int len=n;

dfs(0,n-1);
printf("%d\n",dp[0][n-1]);
return 0;

}


滚动数组版本

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>
#include <set>
#include <vector>
using namespace std;
int min(int a,int b)
{return a<b?a:b;}
int min(int a,int b,int c)
{
return min(c,min(a,b));
}
char tm[5005];
short dp[2][5005];
int main()
{
int n;
cin>>n;
scanf("%s",tm);
int len=n;
int i,j;

for (i=n-1;i>=0 ;i--)
{

for (j=i+1;j<n;j++)
{
if (tm[i]==tm[j])
dp[i&1][j]=dp[(i+1)&1][j-1];
else
dp[i&1][j]=min(dp[(i+1)&1][j],dp[i&1][j-1])+1;  //因为推dp[i][j]需要(后面)i+1的情况和(前面)j-1的情况,所以决定了2个循环的方向不同

}
}

printf("%d\n",dp[0][n-1]);
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: