zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    LIST组件使用总结
    openlayers之interaction(地图交互功能)
    vbind:class绑定样式,决定样式的显示与否
    cesium之measure功能实现
    Cesium渲染效果差,锯齿明显,解决办法
    CSS让DIV层叠 两个DIV或多个DIV顺序重叠加
    ES6之import/export命令
    vantui:
    Openlayers简单要素的添加
    Vue中的this表示?
  • 原文地址:https://www.cnblogs.com/h-hkai/p/7416433.html
Copyright © 2011-2022 走看看