原题:
It’s all true. But we still have a chance; only if you can help with your math skills. You see, the blueprint of a cyborg DNA is complicated. The human DNA could be expressed by the arrangement of A (Adenine), T (Thiamine), G (Guanine) C (Cytosine) only. But for the cyborgs, it can be anything from
A to X. But that has made the problem only five folds more complicated. Its their ability to synthesize two DNAs from two different cyborgs to create another with all the quality of the parent that gives us the shriek. We came to know that the relative ordering of the A, B, C, …, X in a cyborg gene is crucial. A cyborg with a gene “ABAAXGF” is quite different from the one with“AABXFGA”. So when they synthesize the genes from two cyborgs, the relative order of these elements in both the parents has to be maintained. To construct a gene by joining the genes of the parents could have been very simple if we could put the structure from the first parent just before the structure of the second parent. But the longer the structure gets, the harder it gets to create a cyborg from that structure. The cyborgs have found a cost effective way of doing this synthesis. Their resultant genes are of the shortest possible
length. For example, they could combine “ABAAXGF” and“AABXFGA” to form “AABAAXGFGA”. But thats only one of the cyborgs that can be created from these genes. This“cost effective synthesis” can be done in many other ways. We require you to find the shortest length of the gene structure that maintains the relative ordering of the elements in the two parent genes. You are also required to count the number of unique cyborgs that can be created from these two parents. Two cyborgs are different when their gene structures differ in at least one place.
Input
The first line of the input gives you the number of test cases, T (1 ≤ T ≤ 15). Then T test cases follow. Each of the test cases consists of two lines. The first line would give you the gene structure of the first parent, and the second line would give you the structure of the second parent. These structures
are represented by strings constructed from the alphabet ‘A’ to ‘X’. You can assume that the length of these strings does not exceed 30 characters.
Output
For each of the test cases, you need to print one line of output. The output for each test case starts
with the test case number, followed by the shortest length of the gene structure and the number of
unique cyborgs that can be created from the parent cyborgs. You can assume that the number of new
cyborgs will always be less than 2 32 . Look at the sample output for the exact format.
Illustration: The first test case is illustrated below:
Sample Input
3
ABAAXGF
AABXFGA
ABA
BXA
AABBA
BBABAA
Sample Output
Case #1: 10 9
Case #2: 4 1
Case #3: 8 10
中文:
给你两个字符串,让你找出一个字符串s,字符串s“包含”这两个字符串,可以称为最短公共序列(注意不是子序列)。然后输出这个序列的长度,再输出这个序列在这个最短的长度下有多少种。
注意,有空串,要用getline或者gets
#include<bits/stdc++.h>
using namespace std;
string s1,s2;
int dp[35][35];
int cnt;
void dfs(int i,int j)
{
if(i==0||j==0)
{
cnt++;
return;
}
if(s1[i-1]==s2[j-1])
{
dfs(i-1,j-1);
}
else
{
if(dp[i-1][j]==dp[i][j-1])
{
dfs(i-1,j);
dfs(i,j-1);
}
else
{
if(dp[i-1][j]>dp[i][j-1])
dfs(i,j-1);
else
dfs(i-1,j);
}
}
}
int main()
{
ios::sync_with_stdio(false);
int t,m=1;
cin>>t;
cin.get();
while(t--)
{
getline(cin,s1);
getline(cin,s2);
// cin>>s1>>s2;
for(int i=0;i<=s1.size();i++)
{
for(int j=0;j<=s2.size();j++)
dp[i][j]=INT_MAX;
}
cnt=0;
dp[0][0]=0;
for(int i=1;i<=s1.size();i++)
{
dp[i][0]=i;
}
for(int j=1;j<=s2.size();j++)
{
dp[0][j]=j;
}
for(int i=1;i<=s1.size();i++)
{
for(int j=1;j<=s2.size();j++)
{
if(s1[i-1]==s2[j-1])
{
dp[i][j]=dp[i-1][j-1]+1;
}
else
{
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+1;
}
}
}
dfs(s1.size(),s2.size());
cout<<"Case #"<<m++<<": "<<dp[s1.size()][s2.size()]<<" "<<cnt<<endl;
}
return 0;
}
解答:
比较简单的一道动态规划问题,由于是两个字符串表达出的结果状态,所以,可以设置状态为
dp[i][j]
表示第一个字符串s1和第二个字符串s2,在长度分别为前i个字符和前j个字符时组成的最短公共序列是多少。
那么状态转移方程可以写成
dp[i][j]=
{
dp[i-1][j-1]+1 (当s1[i]==s2[j]时)
min(dp[i-1][j],dp[i][j-1])+1 (当s1[i]!=s2[j]时)
}
可以理解为,如果字符s[i]和s2[j]相同,那么当前状态只需要在上一个状态多加上一个相同的字符即可。
否则,找到短的那一个状态,加上短的那个字符即可。
(自己画一个二维表格就能看出来)
最后,用dfs反推状态转移方程,寻找路径数目即为答案。