1. 程式人生 > >2016級算法第四次上機-E.Bamboo and the Ancient Spell

2016級算法第四次上機-E.Bamboo and the Ancient Spell

eof 函數 刪除 code com length blog 動態規劃 暴力

Bamboo and the Ancient Spell

分析

可能英文讀題難度比較大,但是只要看到全大寫的 "THE LONGEST COMMON SUBSEQUENCE !"應該就清楚這是考什麽的了。
最長公共子序列:可以不連續。序列長度很大時,暴力方法非常費時,這也是一道比較經典的《算法導論》上的動態規劃題。

設序列X=和Y=的一個最長公共子序列Z=,則:
若xm=yn,則zk=xm=yn且Zk-1是Xm-1和Yn-1的最長公共子序列;
若xm≠yn且zk≠xm ,則Z是Xm-1和Y的最長公共子序列;
若xm≠yn且zk≠yn ,則Z是X和Yn-1的最長公共子序列。

核心


c[i,j] = c[i,j]=0 (if i=0 or j=0)
c[i,j] = c[i-1,j-1]+1(i,j>0 and xi=yj)
c[i,j] = max(c[i,j-1],c[i-1,j])(i,j>0 and xi!=yj)

特別:# ?

對#的處理方式:刪除;替換;條件判斷
?:比較相等的時候加上等於?的條件

其中刪除:string自帶的erase等函數、或者for循環。都要註意字符串長度的變化

代碼如下:

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
using namespace std; string s1,s2; int c[150][150]; int main() { while(cin>>s1>>s2) { int len1 = s1.length(); int len2 = s2.length(); memset(c,0,sizeof(c)); for(int i = 1;i<=len1;i++) for(int j = 1;j<=len2;j++) { if
(s1[i-1]!='#'&&s2[j-1]!='#'&&(s1[i-1]==s2[j-1]||s1[i-1]=='?'||s2[j-1]=='?')) c[i][j]=c[i-1][j-1]+1; else c[i][j]=max(c[i-1][j],c[i][j-1]); } printf("%d\n",c[len1][len2]); } }

附一個簡單char數組刪除#的代碼:

void prepro()
{
    int i,j;
    for(i = 1; s1[i]!='\0'; i++)
        if(s1[i]=='#')
        {
            for(j=i; s1[j]!='\0'; j++)
                s1[j]=s1[j+1];
            i--;
        }
    for(i = 1; s2[i]!='\0'; i++)
        if(s2[i]=='#')
        {
            for(j=i; s2[j]!='\0'; j++)
                s2[j]=s2[j+1];
            i--;
        }
}

2016級算法第四次上機-E.Bamboo and the Ancient Spell