HDU 1159 Common Subsequence (最长公共子序列 LCS)
题意不多说,就是最长公共子序列的模板题
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<stack>
using namespace std;
#define inf 0x3fffffff
#define LL long long
const int N=1e3+1;
char a[N],b[N];
int dp[N][N];
int main()
{
int la,lb;
while(~scanf("%s%s",a+1,b+1))
{
memset(dp,0,sizeof(dp));
la=strlen(a+1),lb=strlen(b+1);
for(int i=1;i<=la;i++)
for(int j=1;j<=lb;j++)
{
if(a[i]==b[j]) 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[la][lb]);
}
}
HDU 1503 Advanced Fruits (最长公共子序列+递归输出)
题意:给你两串字符串,将两字符串结合起来形成一串,公共子序列只出现一次,将这串序列输出。
两种方法,LCS方面没什么不一样的关键是输出字符串,可以递归也可以非递归。这里要用二维数组标记一下,详细看代码
//非递归
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<stack>
#include<vector>
using namespace std;
#define inf 0x3fffffff
#define LL long long
const int N=110;
char a[N],b[N],s[N*2];
int dp[N][N];
int main()
{
int la,lb,i,j,k;
while(~scanf("%s%s",a+1,b+1))
{
k=0;
memset(dp,0,sizeof(dp));
la=strlen(a+1),lb=strlen(b+1);
for( i=1;i<=la;i++)
for( j=1;j<=lb;j++)
if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
i=la,j=lb;
while(dp[i][j])
{
if(a[i]==b[j])
{
s[k++]=a[i];//将新的字符串存到s数组里面
i--;
j--;
}
else if(dp[i][j-1]>=dp[i-1][j]) s[k++]=b[j--];
else s[k++]=a[i--];
}
//没有公共子序列时直接将两字符串存到s数组里面
while(i!=0) s[k++]=a[i--];
while(j!=0) s[k++]=b[j--];
for(i=k-1;i>=0;i--)
printf("%c",s[i]);
printf("\n");
}
}
//递归
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<algorithm>
#include<iostream>
#include<map>
#include<queue>
#include<vector>
#include<stack>
using namespace std;
#define inf 0x3fffffff
#define LL long long
const int N=101;
int la,lb,dp[N][N],vis[N][N];//vis数组标记用于输出
char a[N],b[N];
void lcs()
{
memset(dp,0,sizeof(dp));
memset(vis,0,sizeof(vis));
for(int i=1;i<=la;i++)
{
for(int j=1;j<=lb;j++)
{
if(a[i]==b[j])
{
dp[i][j]=dp[i-1][j-1]+1;
vis[i][j]=1;
}
else if(dp[i][j-1]>=dp[i-1][j])
{
dp[i][j]=dp[i][j-1];
vis[i][j]=2;
}
else if(dp[i][j-1]<dp[i-1][j])
{
dp[i][j]=dp[i-1][j];
vis[i][j]=3;
}
}
}
}
void out(int i,int j)
{
if(dp[i][j]==0)//当两个字符串没有公共子序列的时候,直接将两字符串输出
{
for(int k=1;k<=i;k++)
printf("%c",a[k]);
for(int k=1;k<=j;k++)
printf("%c",b[k]);
}
//有公共子序列时递归输出
else if(vis[i][j]==1)
{
out(i-1,j-1);
printf("%c",a[i]);
}
else if(vis[i][j]==2)
{
out(i,j-1);
printf("%c",b[j]);
}
else if(vis[i][j]==3)
{
out(i-1,j);
printf("%c",a[i]);
}
}
int main()
{
while(~scanf("%s%s",a+1,b+1))
{
la=strlen(a+1),lb=strlen(b+1);
lcs();
out(la,lb);
printf("\n");
}
}

701

被折叠的 条评论
为什么被折叠?



