LRJ入門經典-0906最短公共父串305
阿新 • • 發佈:2018-12-26
原題
LRJ入門經典-0906最短公共父串305 |
難度級別:B; 執行時間限制:1000ms; 執行空間限制:256000KB; 程式碼長度限制:2000000B |
試題描述 |
給定字串A和字串B,要求找一個最短的字串,使得字串A和B均是它的子序列。 |
輸入 |
輸入包含兩行,每行一個字串,分別表示字串A和字串B。(串的長度不超過30) |
輸出 |
輸出A和B最短公共父串的長度以及在該長度下可以生成的父串個數,用空格隔開。 |
輸入示例 |
ABAAXGF AABXFGA |
輸出示例 |
10 9 |
其他說明 |
ABAAXGF和AABXFGA的最短公共父串之一是AABAAXGFGA,長度為10,滿足該長度的父串一共由9個。 |
分析
程式碼
#include<iostream> #include<algorithm> #include<cstring> using namespace std; typedef long long LL; const int MAXL=32; char S1[MAXL],S2[MAXL]; LL len1,len2,Pa[MAXL][MAXL],Pac[MAXL][MAXL]; LL dpPa(int i1,int i2) { LL& ans=Pa[i1][i2]; if(ans!=-1) return ans; if(i1==0 || i2==0) return ans=max(i1,i2); if(S1[i1]==S2[i2]) return ans=dpPa(i1-1,i2-1)+1; int a=dpPa(i1-1,i2); int b=dpPa(i1,i2-1); return ans=min(a,b)+1; } LL dpPac(int i1,int i2) { LL& ans=Pac[i1][i2]; if(ans!=-1) return ans; if(i1==0 || i2==0) return ans=1; if(S1[i1]==S2[i2]) return ans=dpPac(i1-1,i2-1); LL sl1=dpPa(i1-1,i2),sl2=dpPa(i1,i2-1); if(sl1==sl2) ans=dpPac(i1-1,i2)+dpPac(i1,i2-1); else if(sl1<sl2) ans=dpPac(i1-1,i2); else ans=dpPac(i1,i2-1); return ans; } int main() { gets(S1+1),gets(S2+1); len1=strlen(S1+1),len2=strlen(S2+1); memset(Pa,-1,sizeof(Pa)),memset(Pac,-1,sizeof(Pac)); cout<<dpPa(len1,len2)<<" "<<dpPac(len1,len2)<<endl; /*for(int i=0;i<=len1;i++) { for(int j=0;j<=len2;j++) cout<<Pa[i][j]<<" "; cout<<endl; } cout<<endl; for(int i=0;i<=len1;i++) { for(int j=0;j<=len2;j++) cout<<Pac[i][j]<<" "; cout<<endl; }*/ return 0; }