POJ 1159 Palindrome && HDU 1159 Common Subsequence

来源:互联网 发布:中国互联网中心 知乎 编辑:程序博客网 时间:2024/05/29 10:56

1、先说说杭电的1159吧!

这道题是基础动规,比较简单!

就是要你求最长的公共子序列(不要优化)

动态转移方程: dp[i+1][j+1]=(a[i]=b[i])?dp[i][j]+1:max(dp[i+1][j],dp[i][j+1])

AC代码: 

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define N 520char a[N],b[N];int dp[N][N];int main(){    int i,j,len_a,len_b;    while(scanf("%s %s",a,b)!=EOF)    {        len_a=strlen(a);        len_b=strlen(b);        for(i=1;i<=len_a;i++)            for(j=1;j<=len_b;j++)            {                if(a[i-1]==b[j-1])                    dp[i][j]=dp[i-1][j-1]+1;                else                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);            }        printf("%d\n",dp[len_a][len_b]);    }    return 0;}

2、再说POJ1159:

题意是给你一个字符串,要你算出它成为回文串需要多少字母

Ab3bd
db3bA
本质为求字符串及其逆序串的最长公共子序列(LCS)
如果你还想用刚刚那方法,不好意思,空间复杂度为5K*5K
果断送给了POJ1个Memory Limit Exceeded!
之前学了个滚动数组来优化空间,现在可以考虑了滚动数组优化空间复杂度
注意到dp[i][j]只和dp[i-1][j-1],dp[i-1][j],dp[i][j-1]三个值相关,我们可以只保留两行的数据即可,这样使用两个数组滚动计算即可
所以,AC代码:
#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;#define N 5005int dp[2][N];char str[N],cstr[N];int main(){    int i,j,t;    scanf("%d",&t);    scanf("%s",str);    for(i=0;i<t;i++){        cstr[i]=str[t-i-1];        dp[0][i]=dp[1][i]=0;    }    dp[0][t]=dp[1][t]=0;    for(i=1;i<=t;i++)        for(j=1;j<=t;j++)        {            if(str[i-1]==cstr[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]);        }    printf("%d\n",t-dp[t%2][t]);    return 0;}





1 0
原创粉丝点击