51nod 1006 1006 最长公共子序列Lcs
2017-04-02 00:04
274 查看
写在前面,这个代码调试了很久才弄出来,最后还是发现下标有问题,以后处理这种数组下标的问题还是要明确矩阵下标范围
(1) Ax = By
那么它们L(Ax, By)的最后一项一定是这个元素!
为什么呢?为了方便,我们令t = Ax = By, 我们用反证法:假设L(x,y)最后一项不是t,
则要么L(x,y)为空序列(别忘了这个),要么L(x,y)的最后一项是Aa=Bb ≠ t, 且显然有a < x, b < y。无论是哪种情况我们都可以把t接到这个L(x,y)后面,从而得到一个更长的公共子序列。矛盾!
如果我们从序列Ax中删掉最后一项ax得到Ax-1,从序列By中也删掉最后一项by得到By-1,(多说一句角标为0时,认为子序列是空序列),则我们从L(x,y)也删掉最后一项t得到的序列是L(x – 1, y - 1)。为什么呢?和上面的道理相同,如果得到的序列不是L(x - 1, y - 1),则它一定比L(x - 1, y - 1)短(注意L(,)是个集合!),那么它后面接上元素t得到的子序列L(x,y)也比L(x - 1, y - 1)接上元素t得到的子序列短,这与L(x, y)是最长公共子序列矛盾。
因此L(x, y) = L(x - 1, y - 1) 最后接上元素t
LCS(Ax, By) = LCS(x - 1, y - 1) + 1
(2) Ax ≠ By
仍然设t = L(Ax, By), 或者L(Ax, By)是空序列(这时t是未定义值不等于任何值)。
则t ≠ Ax和t ≠ By至少有一个成立,因为t不能同时等于两个不同的值嘛!
(2.1) 如果t ≠ Ax,则有L(x, y)= L(x - 1, y),因为根本没Ax的事嘛。
LCS(x,y) = LCS(x – 1, y)
(2.2) 如果t ≠ By,l类似L(x, y)= L(x , y - 1)
LCS(x,y) = LCS(x, y – 1)
可是,我们事先并不知道t,由定义,我们取最大的一个,因此这种情况下,有LCS(x,y) = max(LCS(x – 1, y) , LCS(x, y – 1))。
看看目前我们已经得到了什么结论:
LCS(x,y) =
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
这时一个显然的递推式,光有递推可不行,初值是什么呢?
显然,一个空序列和任何序列的最长公共子序列都是空序列!所以我们有:
LCS(x,y) =
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
(3) 0 如果x = 0或者y = 0
仍然考虑那个递推式,我们LCS(x,y)的值来源的三种情况:
(1) LCS(x – 1, y – 1) + 1如果Ax = By
这对应L(x,y) = L(x,- 1 y- 1)末尾接上Ax
(2.1) LCS(x – 1, y) 如果Ax ≠ By且LCS(x – 1, y) ≥LCS(x, y – 1)
这对应L(x,y)= L(x – 1, y)
(2.2) LCS(x, y – 1) 如果Ax ≠ By且LCS(x – 1, y) <LCS(x, y – 1)
这对应L(x,y) = L(x, y – 1)
(3) 0 如果 x
=0或者y = 0
这对应L(x,y)=空序列
注意(2.1)和(2.2) ,当LCS(x – 1, y) = LCS(x, y – 1)时,其实走哪个分支都一样,虽然长度时一样的,但是可能对应不同的子序列,所以最长公共子序列并不唯一。
(1) Ax = By
那么它们L(Ax, By)的最后一项一定是这个元素!
为什么呢?为了方便,我们令t = Ax = By, 我们用反证法:假设L(x,y)最后一项不是t,
则要么L(x,y)为空序列(别忘了这个),要么L(x,y)的最后一项是Aa=Bb ≠ t, 且显然有a < x, b < y。无论是哪种情况我们都可以把t接到这个L(x,y)后面,从而得到一个更长的公共子序列。矛盾!
如果我们从序列Ax中删掉最后一项ax得到Ax-1,从序列By中也删掉最后一项by得到By-1,(多说一句角标为0时,认为子序列是空序列),则我们从L(x,y)也删掉最后一项t得到的序列是L(x – 1, y - 1)。为什么呢?和上面的道理相同,如果得到的序列不是L(x - 1, y - 1),则它一定比L(x - 1, y - 1)短(注意L(,)是个集合!),那么它后面接上元素t得到的子序列L(x,y)也比L(x - 1, y - 1)接上元素t得到的子序列短,这与L(x, y)是最长公共子序列矛盾。
因此L(x, y) = L(x - 1, y - 1) 最后接上元素t
LCS(Ax, By) = LCS(x - 1, y - 1) + 1
(2) Ax ≠ By
仍然设t = L(Ax, By), 或者L(Ax, By)是空序列(这时t是未定义值不等于任何值)。
则t ≠ Ax和t ≠ By至少有一个成立,因为t不能同时等于两个不同的值嘛!
(2.1) 如果t ≠ Ax,则有L(x, y)= L(x - 1, y),因为根本没Ax的事嘛。
LCS(x,y) = LCS(x – 1, y)
(2.2) 如果t ≠ By,l类似L(x, y)= L(x , y - 1)
LCS(x,y) = LCS(x, y – 1)
可是,我们事先并不知道t,由定义,我们取最大的一个,因此这种情况下,有LCS(x,y) = max(LCS(x – 1, y) , LCS(x, y – 1))。
看看目前我们已经得到了什么结论:
LCS(x,y) =
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
这时一个显然的递推式,光有递推可不行,初值是什么呢?
显然,一个空序列和任何序列的最长公共子序列都是空序列!所以我们有:
LCS(x,y) =
(1) LCS(x - 1,y - 1) + 1 如果Ax = By
(2) max(LCS(x – 1, y) , LCS(x, y – 1)) 如果Ax ≠ By
(3) 0 如果x = 0或者y = 0
仍然考虑那个递推式,我们LCS(x,y)的值来源的三种情况:
(1) LCS(x – 1, y – 1) + 1如果Ax = By
这对应L(x,y) = L(x,- 1 y- 1)末尾接上Ax
(2.1) LCS(x – 1, y) 如果Ax ≠ By且LCS(x – 1, y) ≥LCS(x, y – 1)
这对应L(x,y)= L(x – 1, y)
(2.2) LCS(x, y – 1) 如果Ax ≠ By且LCS(x – 1, y) <LCS(x, y – 1)
这对应L(x,y) = L(x, y – 1)
(3) 0 如果 x
=0或者y = 0
这对应L(x,y)=空序列
注意(2.1)和(2.2) ,当LCS(x – 1, y) = LCS(x, y – 1)时,其实走哪个分支都一样,虽然长度时一样的,但是可能对应不同的子序列,所以最长公共子序列并不唯一。
//@auther zhou //@Number 201408070203 //@start time: //@finish time: /*@此处注意: */ /* 测试数据 */ #include<iostream> #include<cstring> #include<vector> #include<cmath> #include<algorithm> using namespace std; int dp[1002][1002]={0}; int main(){ string a1,a2; cin>>a1>>a2; int l1=a1.length(),l2=a2.length(); //cout<<"a1:"<<a1<<"a2:"<<a2<<"over"<<endl; /* abcbdab bdcaba */ for(int i=0;i<=l1;i++){ for(int j=0;j<=l2;j++){ if(i==0||j==0) dp[i][j]=0; else if(a1[i-1]==a2[j-1]){ // cout<<"a1[i]==a2[j]"<<i<<j<<a1[i]<<a2[j]<<endl; dp[i][j]=dp[i-1][j-1]+1; } else { // cout<<"a1[i]不等于a2[j]"<<"i:"<<i<<"j:"<<j<<endl; dp[i][j]=max(dp[i-1][j],dp[i][j-1]); } } } // for(int i=0;i<=l1;i++){ // for(int j=0;j<=l2;j++){ // cout<<dp[i][j]<<" "; // } // cout<<endl; // //} string x; int i=l1,j=l2; while(dp[i][j]){ //else m=max(dp[i-1][j],dp[i][j-1]); if(dp[i][j]==dp[i-1][j]){ i--; } else if(dp[i][j]==dp[i][j-1])j--; else{ x.push_back(a1[i-1]); i--;j--; } } for(int q=x.size()-1;q>=0;q--) cout<<x[q]; return 0; }
相关文章推荐
- 【51NOD-0】1006 最长公共子序列Lcs
- 51Nod 1006 - 最长公共子序列(Lcs)
- 51Nod- 1006 最长公共子序列Lcs(动态规划)
- lcs 51nod 1006 最长公共子序列Lcs
- 最长公共子序列(Lcs)51NOD-1006
- 51nod 1006 最长公共子序列Lcs(打印路径)
- [51nod]1006 最长公共子序列Lcs
- 51nod 1006 最长公共子序列Lcs(经典动态规划)
- 51Nod 1006 最长公共子序列Lcs(DP)
- 51nod 1006 最长公共子序列Lcs
- 51nod 1006 最长公共子序列Lcs
- 51nod 1006:最长公共子序列Lcs
- 51Nod 1006 最长公共子序列Lcs
- 51nod 1006 最长公共子序列Lcs
- 51nod 1006:最长公共子序列Lcs
- 51nod 1006 最长公共子序列Lcs
- 51Nod 1006 最长公共子序列Lcs问题 模板题
- 51nod 1006 最长公共子序列Lcs
- 51Nod 1006 最长公共子序列Lcs (输出)