zoukankan      html  css  js  c++  java
  • LibreOJ 2424 子串

    题目链接:LibreOJ 2424 子串

    题目大意:

    题解:
    (dp[j][k])表示字符串(A)判断到第(i)个字符且一定取第(i)个字符,组成字符串(B)的前(j)个字符,用了(k)个子串的方案数。
    (DP[j][k])表示字符串(A)判断到第(i)个字符但不一定取第(i)个字符,组成字符串(B)的前(j)个字符,用了(k)个子串的方案数。

    1. (A[i-1] eq B[j-1]),则(dp[j][k] = 0)

    2. (A[i-1]=B[j-1]),可以选择将(A[i-1])加在(A[i-2])后面算作一个子串,则此时(A[i-2])必须可取且要一定取,方案数为(dp[j-1][k]);若将(A[i-1])算作一个新的子串,则(A[i-2])不一定取,方案数为(DP[j-1][k-1]),则状态转移方程为:

    [left{egin{aligned}dp[j][k] &= dp[j - 1][k] + DP[j - 1][k - 1],&A[i-1]= B[j-1]\dp[j][k] &= 0,&A[i-1] eq B[j-1]end{aligned} ight. ]

    [DP[j][k] = sum_{1}^{i} dp[j][k] ]

    看到这肯定发现(i)所在的那一维被压缩了,所以在(j)的循环里,(j)是从(m)(1)递减更新答案的(可以联想(01)背包压缩成一维数组)。

    #include <iostream>
    #include <string>
    using namespace std;
    #define N 1010
    const int mod = 1e9 + 7;
    
    int dp[210][210], DP[210][210], n, m, t;
    string a, b;
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
        cin >> n >> m >> t;
        cin >> a >> b;
        dp[0][0] = DP[0][0] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = m; j >= 1; --j) {
                for (int k = 1; k <= t; ++k) {
                    if (a[i - 1] == b[j - 1]) {
                        dp[j][k] = (dp[j - 1][k] + DP[j - 1][k - 1]) % mod;
                        DP[j][k] = (DP[j][k] + dp[j][k]) % mod;
                    } else {
                        dp[j][k] = 0;
                    }
                }
            }
        }
        cout << DP[m][t];
        return 0;
    }
    
  • 相关阅读:
    mysql 压缩备份 压缩还原 命令
    $' ': command not found
    CentOS7查看和关闭防火墙
    Linux系统运维故障排查
    使用netstat、lsof查看端口占用情况
    一道关于二叉树遍历的题目
    curl常用传参方式
    vm centos7中用NAT模式配置上网
    laravel使用过程中一些总结
    MySQL Replication
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/15068164.html
Copyright © 2011-2022 走看看