您的位置:首页 > 产品设计 > UI/UE

暑期dp46道(29) HDOJ 1503 Advanced Fruits 最长公共子序列

2016-08-11 15:22 561 查看
题目链接:HDOJ 1503

题意:给定两个字符串,输出任意一个满足条件的字符串;

条件,给定的两个字串都是该字符串的子序列且该字串的长度最短。

题解:这题很容易推出待求字串的长度和两串的最长公共子序列有关,公共部分输出一次,两字符串各私有的各个输
出;

而私有不私有在求解最长公共子序列的时候,每个子问题都可以得出;

例如两个字符串str1和str2,dp[i][j]表示str1的前i个字符和str2的前j个字符的最长公共子序列。

1):

dp[i][j] = dp[i - 1][j - 1]+1;str1[i-1]和str2[j-1]视为两字符串共有;vis[x][y] = 1;

2):

dp[i][j] = dp[i - 1][j];str1[i-1]为str1私有;
vis[x][y] = 0;

  3):   

dp[i][j] = dp[i][j - 1];str2[j-1]为str2私有;
vis[x][y] = -1;

代码:

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
#define Max(a,b) ((a>b)?a:b)
#define Min(a,b) ((a<b)?a:b)
#define debug 0
#define M(a) memset(a,0,sizeof(a))
#define INF 1 << 28

const int maxn = 100 + 5;
char str1[maxn],str2[maxn],dp[maxn][maxn],len1,len2,vis[maxn][maxn];
void print(int x,int y)//判断str1[x-1]和str2[y-1]相对私有或共有输出
{
if(x == 0 && y == 0)
return;

if(vis[x][y] == 1)
{
print(x - 1, y - 1);
putchar(str1[x - 1]);
}
else
{
if(vis[x][y] == 0)
{
print(x - 1, y);
putchar(str1[x - 1]);
}
else
{
print(x, y - 1);
putchar(str2[y - 1]);
}
}
}
void Do()
{
for(int i = 0;i <= len2;i++)
{
vis[0][i] = -1;//初始化str2私有
}

for(int i = 1; i <= len1; i++)
for(int j = 1; j <= len2; j++)
{
if(str1[i - 1] == str2[j - 1])
{
dp[i][j] = dp[i - 1][ j - 1]+1;
vis[i][j] = 1;
}
else
if(dp[i - 1][j] >= dp[i][j - 1])
{
dp[i][j] = dp[i - 1][j];
vis[i][j] = 0;
}
else
{
dp[i][j] = dp[i][j - 1];
vis[i][j] = -1;
}
}

print(len1,len2);
putchar('\n');
}
int main()
{
#if debug
freopen("in.txt","r",stdin);
#endif //debug
while(~scanf("%s%s",str1,str2))
{
M(dp);
M(vis);//初始化时都设为str1私有
len1 = strlen(str1);
len2 = strlen(str2);
Do();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息