Problem G: 沉迷字符的WJJ (LCS)

Contest - 河南省多校连萌(四)

Problem G: 沉迷字符的WJJ

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 6  Solved: 5

SubmitWeb Board

Description

WJJ最近迷恋上了字符串,每次大家一起吃饭时他都会在大家面前炫耀一番新学的知识,于是
KKK和FFF决定难为一下WJJ。KKK和FFF分别写一个字符串s1和s2,要求WJJ也写一个字符串s3。
要求WJJ回答两个问题:
       1、s1和s2都为s3的子序列并且使s3的长度最短
       2、s3的组成方案有多少种?
 

Input

  第一行输入一个t,表示t组数据
   然后每组数据输入两个字符串,分别为s1,s2, 0<|s1|<=30, 0<|s2|<=30

Output

输出两个数分别为满足条件的s3的长度len1和方案数sum(sum小于2^63),输出占一行

Sample Input

3
ALKJ SADIU
AAA BBB
ABABAB BABABA

Sample Output

8 20
6 20
7 2

HINT

 1 #include <bits/stdc++.h>
 2  
 3 using namespace std;
 4  
 5 char s1[45], s2[45];
 6 long long dp[45][45], sum[45][45];
 7  
 8 int main ()
 9 {
10     int t;
11     cin >> t;
12     while(t--)
13     {
14         cin >> s1+1 >> s2+1;
15         int m = strlen(s1+1);
16         int n = strlen(s2+1);
17         memset(sum, 0, sizeof(sum));
18         for(int i = 0;i <= m;i++) dp[i][0] = i, sum[i][0] = 1;//初始化
19         for(int i = 0;i <= n;i++) dp[0][i] = i, sum[0][i] = 1;
20         for(int i = 1;i <= m;i++)
21             for(int j = 1;j <= n;j++)
22         {
23             if(s1[i] == s2[j])
24             {
25                 dp[i][j] = dp[i-1][j-1] + 1;
26                 sum[i][j] = sum[i-1][j-1];
27             }
28             else
29             {
30                 dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1;
31                 if(dp[i][j-1] >= dp[i-1][j]) sum[i][j] += sum[i-1][j];
32                 if(dp[i-1][j] >= dp[i][j-1]) sum[i][j] += sum[i][j-1];
33             }
34         }
35         printf("%lld %lld
", dp[m][n], sum[m][n]);
36     }
37     return 0;
38 }

LCS的变形, dp[i][j]就是s1中前i个字符和s2中前j个字符可以得到的满足条件的长度
当s1[i] == s2[j]时 dp[i][j] = d[i-1][j-1] + 1
不相等时 dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + 1    //在dp[i-1][j-1]的基础上加上s1或s2中的一个字符取其最短,然后再加一
sum[i][j]表示方案数
当s1[i] == s2[j]时 sum[i][j] = sum[i-1][j-1]      //方案数不变
不相等时 如果dp[i][j-1] == dp[i-1][j], 那么两个方向都可以选择, 所以 sum[i][j] = sum[i-1][j] + sum[i][j-1]
如果dp[i][j-1] < dp[i-1][j] sum[i][j] = sum[i][j-1]    //长度最短时的方案数
如果dp[i][j-1] > dp[i-1][j] sum[i][j] = sum[i-1][j]

感觉这种题如果真正明白了,动态规划的原理其实也没有那么难,这一题的关键主要是理解上面的那段题解。

永远渴望,大智若愚(stay hungry, stay foolish)
原文地址:https://www.cnblogs.com/h-hkai/p/7416433.html