2016級算法第四次上機-E.Bamboo and the Ancient Spell
阿新 • • 發佈:2017-12-04
eof 函數 刪除 code com length blog 動態規劃 暴力 :
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)
Bamboo and the Ancient Spell
分析
可能英文讀題難度比較大,但是只要看到全大寫的 "THE LONGEST COMMON SUBSEQUENCE !"應該就清楚這是考什麽的了。
最長公共子序列:可以不連續。序列長度很大時,暴力方法非常費時,這也是一道比較經典的《算法導論》上的動態規劃題。
設序列X=
若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