首页 > 其他分享 >[刷题笔记] Luogu P2679 [NOIP2015 提高组] 子串

[刷题笔记] Luogu P2679 [NOIP2015 提高组] 子串

时间:2023-08-23 15:11:18浏览次数:46  
标签:子串 NOIP2015 int Luogu scanf 不选 字串 P2679 include

Problem

Description

我们可以换个思路。

从字符串 \(A\) 中拿出 \(k\) 个字串使其变成 \(B\)。求有几种不同的方案?

Analysis

我们发现 \(A\) 中的一个字符取或者不取影响后面的决策,这并不代表它一定有后效性,我们可以记录这一层状态。

和最长公共子序列同理,定义 \(f_{i,j,k,l}(\forall l \in \{1,0\})\) 表示前 \(i\) 位 \(A\),前 \(j\) 位 \(B\),共用 \(k\)个字串,\(A_i\) 选或者不选时的方案数。

每次开始讨论前初始化令 \(f_{i,j,k,0}=f_{i,j,k,1}=0\)。因为接下来都是更新操作。

接下来开始分类讨论。

  • 首先所有情况\(A_i\) 都可以不选,不管是否 \(A_i = B_j\) 。我们这样枚举的目的是尽可能一一对应。所以 \(f_{i,j,k,0}=f_{i-1,j,k,0}+f_{i-1,j,k,1}\)

Explanation:\(A_i\) 不能选,则 \(B\) 不改变。显然 \(A_{i-1}\) 选或者不选都可以推到到这一步。所以等于他俩方案数的和。

  • 当 \(A_i = B_j\) ,这种情况我们可以选择 \(A_i\)。则满足 \(f_{i,j,k,1}=f_{i-1,j-1,k,1}+f_{i-1,j-1,k-1,0}+f_{i-1,j-1,k,0}+f_{i-1,j-1,k-1,1}\)。

Explanation:显然这一位属于公共子串。我们可以把它和上一位归到一个字串内,也可以单独另开一个字串。这都是算作不同的方案数。选或不选也都是不同的方案数。

同时,我们这是四维数组,肯定MLE。容易发现 \(A_i\) 只和 \(A_{i-1}\) 有关系,所以我们显然可以压缩掉第一维状态。

具体实现见代码:

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
using namespace std;
const int N = 300;
const int mod = 1000000007;
int n,m,K;
char s1[3000],s2[N];
int f[N][N][N][3];
int main()
{
//    ios::sync_with_stdio(false);
//    cin.tie(0);
//    cout.tie(0); 
    scanf("%d%d%d",&n,&m,&K);
    scanf("%s",s1+1);
    scanf("%s",s2+1);
    f[0][0][0][0] = 1;
    for(int i=1;i<=n;i++)
    { 
        int op = i & 1;
        f[op][0][0][0] = 1;
        for(int j=1;j<=min(i,m);j++)
        {
            for(int k=1;k<=min(j,K);k++)
            {
                f[op][j][k][0] = f[op][j][k][1] = 0;
                f[op][j][k][0] =  (f[op^1][j][k][0]+f[op^1][j][k][1]) %mod; 
                if(s1[i] == s2[j])
                {
                    f[op][j][k][1] = (f[op^1][j-1][k][1]+f[op^1][j-1][k-1][0]) % mod;
                    (f[op][j][k][1] += f[op^1][j-1][k-1][1]) %= mod;
                }
            }
        }
    }
    printf("%d\n",(f[n&1][m][K][1]+f[n&1][m][K][0])%mod);
}

标签:子串,NOIP2015,int,Luogu,scanf,不选,字串,P2679,include
From: https://www.cnblogs.com/SXqwq/p/17651690.html

相关文章

  • [刷题笔记] [【LGR-155-Div.3】T4] Luogu P9572 「NnOI R2-T4」Colorful Days♪
    ProblemDescription有两个数组\(A,B\),我们可以将\(A\)数组无限次重复拼接。求最少需要多少次拼接使得拼接后的\(A,B\)的最长公共子序列最大。Analysis我们要学会从题目中找到一些信息,比如说本题的数据范围:对于\(100\%\)的数据,保证\(1\leqn,m,S_i,T_i\le10^6\),\(......
  • Luogu P1119 灾后重建
    在洛谷中查看解法1(我想的解法,不完全正确):很常见的套路:将询问按时间排序。时间复杂度:\(O(\;q\,(n\,logn+m)\;)\),即\(10^9\),开\(O2\)才能过。非常麻烦有没有,但我对拍的时候发现了一组数据很奇怪,待会给你们看看,我看看能不能hack#include<bits/stdc++.h>usingnamespacestd......
  • 【LuoGu 1363】幻象迷宫——深度优先搜索 + 读题
    幻象迷宫题目背景(喵星人LHX和WD同心协力击退了汪星人的入侵,不幸的是,汪星人撤退之前给它们制造了一片幻象迷宫。)WD:呜呜,肿么办啊……LHX:momo...我们一定能走出去的!WD:嗯,+U+U!题目描述幻象迷宫可以认为是无限大的,不过它由若干个\(N\timesM\)的矩阵重复组成。矩阵中有的地......
  • Luogu P3369 【模板】普通平衡树 01Tire树解法
    题目传送门闲话:Luogu总共105篇题解中只有4篇01Tire树解法,虽说是非正解但未免也太少了些(貌似也不少?)……总之01Tire树的效率并不低,这道题用01Tire是很轻松的。Q:这题为什么可以用01Tire树解?能否解决一个问题,无非于三个点:可行性,空间,时间。本题要求维护一个有序数集,能进行元素修改......
  • 牛的旅行 luoguP1522 多余的换行造成的影响
    牛的旅行#include<bits/stdc++.h>usingnamespacestd;intread(){intf=1,x=0;charc=getchar();while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){......
  • Luogu P9510 『STA - R3』高维立方体 题解
    题目传送门没见过这玩意,写个题解记下。题目大意周知斐波那契数列定义为:\[\operatorname{fib}(n)=\left\{\begin{aligned}1&&n\le2\\\operatorname{fib}(n-1)+\operatorname{fib}(n-2)&&n>2\end{aligned}\right.\]然后定义(\(n\le0\)函数值为\(0\))\[f(n)......
  • [Luogu P8716] 回文日期 题解
    STEP1:分析题目大意:给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。这一题一眼看出是P2010的升级版,所以要先考虑到超时问题,因为如果一天一天地枚举,时间复杂度会非常高,所以我们不能直接枚举。因为题目只要"回文",所以我们只......
  • LuoguP1717 钓鱼
    题面题目分析动态规划。\(\bullet\)设计状态。思考:我从哪里来?从上一个湖过来。我到哪里去?到下一个湖去\(or\)继续在这个湖钓鱼。设\(dp[pos][tim]\)为前\(pos\)个湖花费了\(tim\)分钟所能钓的最大的鱼数量。\(\bullet\)转移状态。(为了方便计算,我们将题目中的数据......
  • [刷题笔记] Luogu P1725 琪露诺
    ProblemDescription若当前在\(pos\)位置,每次可以在\([pos+l,pos+r]\)区间内任选一个点跳。每跳到一个地方就可以获得这个地方的值,最后跳到位置\(pos\geqn\)即为结束,求如何跳才能使结束的时候获得的值最大?Analysis我们发现所有操作都是在一条链上完成的,显然若再次跳到这个位......
  • 题解 LuoguP3306 [SDOI2013] 随机数生成器
    题目链接:【LuoguP3306】。前置知识OI-Wiki:快速幂,扩展欧几里得算法(exgcd),BabyStep,GiantStep算法。题意很清楚,不说。分析当\(t=x\)时答案很明显为\(1\),即在第一天就可以读到。当\(t\neqx\)时当\(a=0\)时观察一下规律:\[x_1\equivx_1\pmod{p}\]\[x_2\equivb......