题意翻译
【题目描述】
输入两个AAA~ZZZ组成的字符串(长度均不超过303030),找一个最短的串,使得输入的两个串均是它的子序列(不一定连续出现)。你的程序还应统计长度最短的串的个数。
e.g.:ABAAXGFe.g.:ABAAXGFe.g.:ABAAXGF和AABXFGAAABXFGAAABXFGA的最优解之一为AABAAXGFGAAABAAXGFGAAABAAXGFGA,一共有999个解。
【输入格式】
有多组数据。第一行一个整数TTT表示数据组数。接下来的2T2T2T行,每行一个字符串,含义如题所示。
【输出格式】
共TTT行。第iii行格式为
Case #i: x y
其中xxx为最短串的长度,yyy为最优解的个数。
题目描述
输入输出格式
输入格式:输出格式:
输入输出样例
输入样例#1:
复制
3 ABAAXGF AABXFGA ABA BXA AABBA BBABAA
输出样例#1: 复制
View Code
Case #1: 10 9 Case #2: 4 1 Case #3: 8 10
f[i][j]表示第一个处理到i,第二个处理到j的最短长度,g表示个数
注意输入用getline,据说数据很坑
第一次用scanf("%s")没过
#include<bits/stdc++.h> using namespace std; const int maxn = 110; int f[maxn][maxn],g[maxn][maxn],kase=0; int main() { int t; scanf("%d ",&t); while(t--) { memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); string a,b; getline(cin,a); getline(cin,b); int lena=a.size(),lenb=b.size(); for(int i=0;i<=lena;i++) f[i][0]=i,g[i][0]=1; for(int i=0;i<=lenb;i++) f[0][i]=i,g[0][i]=1; for(int i=1;i<=lena;i++) for(int j=1;j<=lenb;j++) { if(a[i-1]==b[j-1]) f[i][j]=f[i-1][j-1]+1; else f[i][j]=min(f[i-1][j],f[i][j-1])+1; } for(int i=1;i<=lena;i++) for(int j=1;j<=lenb;j++) { if(a[i-1]==b[j-1]) g[i][j]=g[i-1][j-1]; else if(f[i-1][j]>f[i][j-1]) g[i][j]=g[i][j-1]; else if(f[i-1][j]<f[i][j-1]) g[i][j]=g[i-1][j]; else g[i][j]=g[i-1][j]+g[i][j-1]; } printf("Case #%d: %d %d ",++kase,f[lena][lenb],g[lena][lenb]); } return 0; }