poj 1159

来源:互联网 发布:ubuntu 安装sqlserver 编辑:程序博客网 时间:2024/05/29 13:47

一种解法是求原序和逆序的最长公共子序列;

第二次方法是dp;

都用的滚动数组,也可以用short减小内存;

第一次知道怎么算内存大小了,哈哈

//5000 * 5000的int ——> 5000 * 5000 * 4 bytes 约(/ (2 ^ 20))等于5 * 5 * 4 MB = 100 MB > 65536 K = 64 M,会MLE的。。

第二种思路

1.当S1==Sn时(字符串头字符和字符串尾部字符相等时),我们的任务便转换为了将S2,S3,S4……S(n-1)变成回文,对吗?

2.当S1!=Sn时,我们又有了两种决策

第一种决策:在字符串序列S1,S2,S3……Sn 的左边添加一个字符,我们设这个字符为Si,使它等于Sn,这样我们就将当前的任务转化为了将S1,S2,S3……S(n-1)变成回文字符串。

第二种决策:在字符串序列S1,S2,S3……Sn 的右边添加一个字符,我们设这个字符为Sk,使他等于S1,这样我们就将当前的任务转化为了将S2,S3,S4……Sn变成回文字符串。

特别是s1!=sn时

第一种

代码如下

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std; int main(){char a[5005],b[5005];int n,dp[2][5005];scanf("%d",&n);scanf("%s",a);for(int i=n-1;i>=0;i--) b[n-1-i]=a[i];memset(dp,0,sizeof(dp));for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(a[i]==b[j]){dp[(i+1)%2][j+1]=dp[i%2][j]+1;}else{dp[(i+1)%2][j+1]=max(dp[i%2][j+1],dp[(i+1)%2][j]);}}printf("%d\n",n-dp[n%2][n]); } 

第二种

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;int main(){int n,dp[2][5005];char a[5005];memset(dp,0,sizeof(dp));scanf("%d",&n);scanf("%s",a);for(int i=n-2;i>=0;i--)for(int j=i;j<n;j++){if(a[i]==a[j]) dp[i%2][j]=dp[(i+1)%2][j-1];else{dp[i%2][j]=min(dp[(i+1)%2][j],dp[i%2][j-1])+1;} }printf("%d\n",dp[0][n-1]); } 


原创粉丝点击