您的位置:首页 > 其它

poj 1159 Palindrome (反串LCS 与 DP两种方法)

2014-02-25 23:00 225 查看
题目链接http://poj.org/problem?id=1159

LCS之前只写了一次,反串了以后都没有反应过来可以用LCS。。。

给出反串LCS代码:

//反串LCS
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

int n;
char s[5005];
char rs[5005];
int dp[2][5005];///滚动数组

int lcs(char* str1,char* str2){
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(str1[i-1]==str2[j-1])
dp[i%2][j]=dp[(i-1)%2][j-1]+1;
else
dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
}
return dp[n%2]
;
}
int main(){

while(cin>>n>>s){
int i;
for(i=0;i<n;i++)
rs[i]=s[n-i-1];
rs[i]='\0';
cout<<n-lcs(s,rs)<<endl;
}
return 0;
}


View Code
但是据说有动态规划的做法,就沿着动态规划的思路想了想,发现其实很简单

给出基本DP做法

/*
动态规划思想
我们先从上至下的分析

以题目数据做例子
假如字符串Ab3bd已经找到最优的最少插入方法,设为dp(Ab3bd)
那么,我们想得出b3bd的最优解
因为A与b3bd的最后一个字符d不相同,说明排除A以后,就可以省掉一个插入,则dp(b3bd)=dp(Ab3bd)-1
同理,dp(Ab3b)=dp(Ab3bd)-1

如果把字符串改成
Ab3bdA
那么dp(b3bdA)=dp(Ab3bd)=dp(Ab3bdA)+1

我们就发现了关系
if(i==j)
dp(i....j)=dp(i+1...j)-1 //此时dp(i+1....j)==dp(i....j-1)
else
dp(i....j)=min( dp(i+1....j)+1,dp(i....j-1)+1 )//此时dp(i+1...j)!=dp(i...j-1)

实现:
设dp[i][j]为从i到j的最优解
可以看出,在求dp[i][j]时,dp[i+1][j]和dp[i][j-1]就已经要求出来了
所以有i递减,j递增的顺序(显然i从n递减,j从i递增)
答案就是 dp[1]

算法时间O(n^2)
*/
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

int n;
char s[5005];
int dp[2][5005];

int main (){
while(cin>>n>>s){
memset(dp,0,sizeof(dp));//dp[i][i]=0
for(int i=n-1;i>=1;i--)
for(int j=i+1;j<=n;j++)
{
if(s[i-1]==s[j-1])
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;
}
cout<<dp[1]
<<endl;
}
return 0;
}


其实后来发现s[i-1]==s[j-1]时,dp[i][j]=dp[i+1][j-1]。。。貌似好一点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: