河南省多校联萌(四)



Problem G: 沉迷字符的WJJ

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 3   Solved: 2

Submit Web 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\n", 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
            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]












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值