pku 1458 pku2250 pku3356 最长公共子序列

都是同一类型的题目,求最长公共子序列

pku1458
#include<iostream>
#include
<string>
#include
<algorithm>
using namespace std;
int main()
{
char s1[1000],s2[1000];
int s[1000],t[1000],l1,l2;
while(scanf("%s %s",s1,s2)==2)
{
l1
=strlen(s1);
l2
=strlen(s2);
memset(s,
0,sizeof(s));
memset(t,
0,sizeof(t));
for(int i=0;i<l1;i++)
{
for(int j=0;j<l2;j++)
{
if(s1[i]==s2[j])
s[j
+1]=t[j]+1;
else
s[j
+1]=t[j+1]>s[j]?t[j+1]:s[j];
}
for(int j=1;j<=l2;j++)
t[j]
=s[j];
}
printf(
"%d\n",t[l2]);
}
return 0;
}

  这题目稍微有点不同,俩个序列的元素不是一个字母或者数字,而是一个单词,但本身还是差不多 的,可惜RE了俩次,在输出是判断条件错了

pku2250
#include<iostream>
#include
<string>
#include
<algorithm>
using namespace std;
char str1[110][31],str2[110][31];
int len1,len2,num,dp[110][110],load[110][110];
void print(int i,int j)
{
if(i==0||j==0) //有一个为 0 就得退出了
return ;
if(load[i][j]==1)
{
print(i
-1,j-1);
printf(
"%s",str1[i-1]);
num
--;
if(num==0)
printf(
"\n\n");
else printf(" ");
}
else if(load[i][j]==0)
print(i
-1,j);
else print(i,j-1);
}
int main()
{
int i=0;
while(scanf("%s",str1[i])==1)
{
while(str1[i][0]!='#')
scanf(
"%s",str1[++i]);
len1
=i;
len2
=0;
scanf(
"%s",str2[len2]);
while(str2[len2][0]!='#')
scanf(
"%s",str2[++len2]);
len2;
for(i=0;i<=len2;i++)
dp[
0][i]=0;
for(i=0;i<=len1;i++)
dp[i][
0]=0;
for(i=1;i<=len1;i++)
{
for(int j=1;j<=len2;j++)
{
if(strcmp(str1[i-1],str2[j-1])==0)
dp[i][j]
=dp[i-1][j-1]+1,load[i][j]=1;
else if(dp[i-1][j]>=dp[i][j-1])
dp[i][j]
=dp[i-1][j],load[i][j]=0;
else dp[i][j]=dp[i][j-1],load[i][j]=-1;
}
}
num
=dp[len1][len2];
print(len1,len2);
i
=0;
}
return 0;
}

  最后这道题目,序列很长,可是很难用滚动数组,应该说,我不知道要怎么用上去,嘻嘻

本来以为先求最长公共子序列,再用最长的序列减掉就可以了,结果真的想错了,看了这个例子就知道了 ACD   CDB 用刚才的方法求的话,输出1 ,但实际上要改动的是俩个字母,即俩个操作,所以老老实实的改了一下转移方程

pku 3356
#include<iostream>
#include
<string>
#include
<algorithm>
using namespace std;
char s1[1005],s2[1005];
int dp[1005][1005];
inline
int min(int a,int b,int c)
{
if (a>b) return b>c?c:b;
return a>c?c:a;
}
int main()
{
int i,j,k,n,m;
while(scanf("%d%s", &n, s1)!=EOF)
{
scanf(
"%d%s",&m, s2);
memset(dp,
0, sizeof(dp));
//注意初始化
for(i = 0; i <= n; i++) dp[i][0] = i;
for(i = 0; i <= m; i++) dp[0][i] = i;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
{
if(s1[i] == s2[j])
dp[i
+1][j+1] = min(dp[i][j], dp[i+1][j]+1, dp[i][j+1]+1);
else dp[i+1][j+1] = min(dp[i][j]+1, dp[i+1][j]+1, dp[i][j+1]+1);
}
printf(
"%d\n",dp[n][m]);
}
return 0;
}

  

posted @ 2011-08-20 23:20  枕边梦  阅读(270)  评论(0编辑  收藏  举报