动态规划经典 最长公共子序列 poj1159
来源:互联网 发布:淘宝开店需要押金吗? 编辑:程序博客网 时间:2024/06/05 05:56
出处http://blog.csdn.net/v_july_v/article/details/6695482
帮我稍微理解了这个思想。
哎~我就是传说中的无脑儿啊!
一个序列X,一个序列Y,
X的下标用i,Y的下标用j,
Xi表示从第一个元素到第i个元素的这个序列。
Yj表示从第一个元素到第j个元素的序列。
xi表示X序列的第i个元素,yj表示Y序列的第j个元素。
我们把序列Xn和Ym的最长公共子序列的长度表示为F(n,m)。
先说一下递归的做法。
假设现在我们想要求F(i,j),
1.如果xi==yj,那么这个xi(或者是yj)一定是Xi和Yj的最长公共子序列的结尾数字,好,继续往下递归求X(i-1)和Y(j-1)的最长公共子序列长度,长度加1就是F(i,j)的值。
2.如果xi!=yj, 那么这个 xi 一定不是Xi和Yj的最长公共子序列的结尾数字,那么结尾的数字在前面,也就是F(i,j)与F(i-1,j)或者与F(i,j-1)相比长度并没有增加,那么我想要他们中最大的啊,于是F(i,j)=max( F(i-1,j),F(i,j-1))。好,那么递归求F(i-1,j)和F(i,j-1)的值。
(你想要的最终结果就把i换成X的长度,j换成Y的长度就是了)
处理一下边界。
那显然就是i==0或者j==0的时候了。F(0,j)或者F(i,0)都是0(这个是显然的吧~你一个什么都没有的序列和任意序列的公共子序列显然是0啊),这样可以返回值了。
我用伪代码写一下啊(其实也不算伪代码……)
这个的前提是你已经读入了X这个序列和Y这个序列了啊。
xi表示X序列的第i个元素,yj表示Y序列的第j个元素。
想求F(i,j):
if( xi==yj ) return F(i-1,j-1)+1;
else return max ( F(i-1,j) , F(i,j-1) ); /*也就是xi!=yj的时候*/
OK,那么我们发现有很多时候有些值是重复计算的。处理方法显然有两种啦,一种是记忆化搜索,一种是动态规划了(倒着这个过程来呗)。
其实网上还有很多大牛,我就不啰嗦那些名词了,什么子问题重复什么的……我只是理解而已,想让我一板一眼地讲出来还是真有难度,想知道具体的可以看他们更加专业化的讲解。
我只说动态规划的。
既然后面的状态需要求出前面的状态,那我何不从前面的状态开始求起,递推出后面的状态呢?
初始的状态是F(i,0)=0而且F(0,j)=0;
那么递推开始了,关键的条件还是不变的。
现在我们想求F(i,j)(它可以由前面的状态推出来哦!注意现在是递归过程的逆着来了,递归是去找前面的状态,动态规划是从底层的状态推出来高层的状态)
if(xi==yj) F(i,j) = F ( i-1 , j-1 ) + 1;
else F(i,j)=( F(i-1,j) , F(i,j-1));
那么一路递推下去,推到两个序列的长度即可。
因为F有两个参数,所以在用代码实现的时候要用二维数组来实现。这里我用了dp数组来表示F这个函数。
好啦终于可以上代码啦。
注意下标的处理。
AC代码
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;const int maxn=1e3+10;const int inf=1e9+10;int dp[maxn][maxn];int main(){ //初始化F(i,0)或者F(0,j)为0; memset(dp,0,sizeof(dp)); char str1[maxn]; char str2[maxn]; scanf("%s %s",str1,str2); int len1=strlen(str1); //cout<<"len is "<<len1<<endl; int len2=strlen(str2);
//从第一个数字开始递推,推到最后一个数字。 for(int i=1;i<=len1;i++) { for(int j=1;j<=len2;j++) {
//注意这里字符串的下标并不是1、2、3、4、5而是0、1、2、3、4所以要处理好。 if(str1[i-1]==str2[j-1])
dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } cout<<dp[len1][len2]<<endl; }}
希望这次南宁的邀请赛能拿个奖。也希望我这个兴趣能一直保持下去咯~
- 动态规划经典 最长公共子序列 poj1159
- 北大POJ1159 Palindrome(动态规划求最长公共子序列)
- Palindrome(补全回文串+最长公共子序列的应用)hdu1513+poj1159+动态规划
- 最长公共子序列(经典的动态规划)
- 动态规划经典问题---最长公共子序列(LCS)
- 经典动态规划之最长公共子序列
- 动态规划有一个经典问题是最长公共子序列
- 动态规划经典问题:寻找最长公共子序列
- 经典代码 南阳oj 动态规划 最长公共子序列
- 动态规划经典之求最长公共子序列LCS
- 动态规划经典——最长公共子序列
- 最长公共子序列&&最长公共子串---[动态规划]
- 动态规划-最长公共子序列、最长公共子串
- Poj1159——最长公共子序列
- poj1159 Palindrome(最长公共子序列)
- HDU1513 && POJ1159 Palindrome 最长公共子序列
- poj1159(dp,最长公共子序列)
- poj1159-Palindrome(最长公共子序列)
- 在modal viewcontroller外点击屏幕dismiss
- 一个把json数据批量插入SQL SERVER 的Python脚本
- MVC @Html控件 TextBoxFor MVC 控件 加属性
- 直白解读网络编程第二节_进程(入门)
- 【背包专题】A
- 动态规划经典 最长公共子序列 poj1159
- iOS项目集成BongSDK,打包提交报@“ERROR ITMS-90171 和ERROR ITMS-90206”错误
- Android开发-自定义View-AndroidStudio(二十七)移动的View
- json串反序列化解析异常
- s:iterator 标签嵌套迭代
- 对于共享电脑的到来,您有什么想说的
- 【链表】单链表循环解决Josephus问题
- java中多线程环境下实现单例的几种方法
- qduoj 基础算法测验1