暑期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;
}
题意:给定两个字符串,输出任意一个满足条件的字符串;
条件,给定的两个字串都是该字符串的子序列且该字串的长度最短。
题解:这题很容易推出待求字串的长度和两串的最长公共子序列有关,公共部分输出一次,两字符串各私有的各个输
出;
而私有不私有在求解最长公共子序列的时候,每个子问题都可以得出;
例如两个字符串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;
}
相关文章推荐
- HDOJ 1503 Advanced Fruits (最长公共子序列 LCS)
- 暑期dp46道(43)--HDOJ 1159 最长公共子序列(可不连续)
- hdoj 1503 Advanced Fruits 【最长公共子序列 变形】
- 暑期dp46道(39)--HDOJ 2870 最大子矩阵面积...
- 暑期dp46道(16)hdoj 1025 Constructing Roads In JGShining's Kingdom最长上升子序列(二分)
- 暑期dp46道(35)--HDOJ 2159 FATE 背包问题
- 暑期dp46道(40)--HDOJ 2830 最大子矩阵面积 额
- hdoj 1503 Advanced Fruits (LCS 变形合并)
- 暑期dp46道(13)——HDOJ 1160FatMouse's Speed 排序+最长严格下降子序列+回溯
- 暑期dp46道(26)HDOJ 1501 Zipper dfs+记忆化搜索
- 暑期dp46道(10)HDOJ 2602 Bone Collect 01背包
- 暑期dp46道(12)--HDOJ 2191 多重背包+二进制优化
- HDU 1503 Advanced Fruits (LCS,DP)
- 暑期dp46道(37) HDOJ 2844 COINS
- 暑期dp46道(44)--HDOJ 1058
- 暑期dp46道(31)--HDOJ 1087 最大上升子序列和 dp(水)
- 暑期dp46道(17)--HDOJ1114 Piggy Bank 完全背包
- 暑期dp46道(21)HDOJ 2059 龟兔赛跑
- 暑期dp46道(23)HDOJ 1059 Dividing 多重背包+二进制优化
- 暑期dp46道(24)HDOJ 1074 Doing Homework 状压dp