动态规划LCS问题( HDU - 1159 Common Subsequence)
2017-02-18 07:48
375 查看
题意:最长公共子集裸
求解LCS问题的解法描述网上有很多很详细的,不过几乎都差不多。大概就是,公共子集Z中,对于zi有三种可能:
1.zi=xk=yj,则dp[k][j]=dp[k-1][j-1]+1;
2.zi=xk&&xk!=yj或者zi=yj&&yj!=xk,这个时候归为一条式子即 dp[k][j]=max(dp[k-1][j],dp[k][j-1]);
当然还存在全不相等的情况,但这种时候最终也会回归到2中。
代码如下:
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(a[i]==b[j]){
dp[i+1][j+1]=dp[i][j]+1;
}else{
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
}
}
}
这道题我是看着题解做的(因为太菜了。。。)不过我看的那位的初始化我不是很理解,后来看到一张图我瞬间想起来刚开学的时候居然看到过求解LCS问题orz。那么初始化其实就是把最左一列和最上一行全部设为0,然后下标从一开始就好了。
就是这张图(出处见水印)。是不是好理解很多。
相同的把左上角加一,不同则取上和左的max,分析就是上文。
这个还可以用来求回文串,把字符串倒一下就好了。其实我第一次看到这张图就是回文串的题目(然而并没有看懂
![](https://img-blog.csdn.net/20170218075749009?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2VpeGluXzM2NDgzNzc0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
完整代码:
/*HDU-1159 LIS问题
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<vector>
#define INF 100000000
#define MAXNUM 1007
#define pi 3.1415926
using namespace std;
char a[MAXNUM];
char b[MAXNUM];
int dp[MAXNUM][MAXNUM];
void lcs(int len1,int len2)
{
/*这样子好理解一点。。*/
int maxlen=max(len1,len2);
for(int i=0;i<=maxlen;i++){
dp[i][0]=0;
dp[0][i]=0;
}
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(a[i]==b[j]){
dp[i+1][j+1]=dp[i][j]+1;
}else{
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
}
}
}
/*别人的初始化*/
// for(int i=0;i<len1;i++){
// for(int j=0;j<len2;j++){
// if(i==0||j==0){
// if(a[i]==b[j])dp[i][j]=1;
// else{
// if(i==0&&j==0)dp[i][j]=0;
// else{
// i==0?dp[i][j]=dp[i][j-1]:dp[i][j]=dp[i-1][j];
// }
// }
/*对其他的处理*/
// }else{
// 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]);
// }
// }
// }
// }
}
int main()
{
while(scanf("%s%s",a,b)!=EOF){
int len1=strlen(a);
int len2=strlen(b);
lcs(len1,len2);
int ans=dp[len1][len2];
printf("%d\n",ans);
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
}
return 0;
}(话说我的前几篇博文一直在被审核。。我到底干了什么。。orz
求解LCS问题的解法描述网上有很多很详细的,不过几乎都差不多。大概就是,公共子集Z中,对于zi有三种可能:
1.zi=xk=yj,则dp[k][j]=dp[k-1][j-1]+1;
2.zi=xk&&xk!=yj或者zi=yj&&yj!=xk,这个时候归为一条式子即 dp[k][j]=max(dp[k-1][j],dp[k][j-1]);
当然还存在全不相等的情况,但这种时候最终也会回归到2中。
代码如下:
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(a[i]==b[j]){
dp[i+1][j+1]=dp[i][j]+1;
}else{
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
}
}
}
这道题我是看着题解做的(因为太菜了。。。)不过我看的那位的初始化我不是很理解,后来看到一张图我瞬间想起来刚开学的时候居然看到过求解LCS问题orz。那么初始化其实就是把最左一列和最上一行全部设为0,然后下标从一开始就好了。
就是这张图(出处见水印)。是不是好理解很多。
相同的把左上角加一,不同则取上和左的max,分析就是上文。
这个还可以用来求回文串,把字符串倒一下就好了。其实我第一次看到这张图就是回文串的题目(然而并没有看懂
完整代码:
/*HDU-1159 LIS问题
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#include<vector>
#define INF 100000000
#define MAXNUM 1007
#define pi 3.1415926
using namespace std;
char a[MAXNUM];
char b[MAXNUM];
int dp[MAXNUM][MAXNUM];
void lcs(int len1,int len2)
{
/*这样子好理解一点。。*/
int maxlen=max(len1,len2);
for(int i=0;i<=maxlen;i++){
dp[i][0]=0;
dp[0][i]=0;
}
for(int i=0;i<len1;i++){
for(int j=0;j<len2;j++){
if(a[i]==b[j]){
dp[i+1][j+1]=dp[i][j]+1;
}else{
dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
}
}
}
/*别人的初始化*/
// for(int i=0;i<len1;i++){
// for(int j=0;j<len2;j++){
// if(i==0||j==0){
// if(a[i]==b[j])dp[i][j]=1;
// else{
// if(i==0&&j==0)dp[i][j]=0;
// else{
// i==0?dp[i][j]=dp[i][j-1]:dp[i][j]=dp[i-1][j];
// }
// }
/*对其他的处理*/
// }else{
// 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]);
// }
// }
// }
// }
}
int main()
{
while(scanf("%s%s",a,b)!=EOF){
int len1=strlen(a);
int len2=strlen(b);
lcs(len1,len2);
int ans=dp[len1][len2];
printf("%d\n",ans);
memset(dp,0,sizeof(dp));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
}
return 0;
}(话说我的前几篇博文一直在被审核。。我到底干了什么。。orz
相关文章推荐
- Common Subsequence 杭电HDU1159 【动态规划LCS】
- HDU 1159 最长公共子序列问题 动态规划
- HDU 1159 最长公共子序列问题 动态规划
- hdu 1503:Advanced Fruits(动态规划 DP & 最长公共子序列(LCS)问题升级版)
- HDU 1159 Common Subsequence (动态规划LCS)
- Hdu 1513 & Poj 1159 (LCS) + Hdu 1025 (LIS)
- HDU 1159 Common Subsequence 动态规划
- HDU1159 Common Subsequence (LCS)
- HDU 1284 钱币兑换问题 动态规划完全背包
- hdu 1159 LCS最大公共子序列
- Common Subsequence(hdu1159(LCS))
- HDU 1024 Max Sum Plus Plus(动态规划,给定一个数组,求其分成m个不相交子段和最大值的问题)
- hdu 1159 Common Subsequence 【LCS 基础入门】
- 动态规划练习二:HDU ACM 1159 Common Subsequence
- Poj1159 Palindrome(动态规划DP求最大公共子序列LCS)
- Poj1159 Palindrome(动态规划DP求最大公共子序列LCS)
- Human Gene Functions - LCS 动态规划 HDU-1080
- 动态规划经典问题---最长公共子序列(LCS)
- hdu 1159 dp lcs nlogn解法
- HDU 1159 Common Subsequence(LCS)