Atcoder ABC329E Stamp 题解 [ 绿 ] [ 线性 dp ]

news/2025/1/9 23:20:30/文章来源:https://www.cnblogs.com/zhr0102/p/18663080

Stamp:难点主要在 dp 转移的细节与分讨上,但通过改变状态设计可以大大简化分讨细节的题。

观察

首先要有一个观察:只要某一个前缀能被覆盖出来,那么无论它后面多出来多少,后面的字符串都可以帮他重新覆盖回去。这也就是 dp 为啥没有后效性的原因。

除此之外,还要注意一个字符串不仅能在其他字符串上面,还能被盖在最下层来达到用子串接着覆盖的效果。

暴力 dp 思路

\(dp_i\) 表示第 \(i\) 个字符的前缀能否被覆盖。每次转移的时候枚举当前位和 \(B\) 的第几个字符匹配,然后判断某一段是否相等,进行转移即可。这个做法感觉比较难写,但肯定没有假。时间复杂度 \(O(nm^2)\),显然可过。

更巧妙的 dp 思路

\(dp_{i,j}\) 表示 \(A\) 匹配到第 \(i\) 个,\(B\) 匹配到第 \(j\) 个是否可行。

那么接下来分为三个情况,这三种情况的前提条件就是 \(A_i=B_j\),否则一定无解:

  • \(j=1\),也就是当前 \(B\) 刚开始匹配。也就是说前面的部分只要能被覆盖出就行了,不管他前面匹配到多少个,则 \(dp_{i,j}\gets dp_{i,j}\bigvee_{k=1}^{m}dp_{i-1,k}\)
  • 这个字符接着上一个字符覆盖,则 \(dp_{i,j}\gets dp_{i,j}\bigvee dp_{i-1,j-1}\)
  • 这个字符被盖在最下面,用自己的后缀覆盖。这种情况需要满足的条件是前一个字符串一定要先被覆盖完,才可以在下一个字符串覆盖前覆盖在它的下面。则 \(dp_{i,j}\gets dp_{i,j}\bigvee dp_{i-1,m}\)

直接这样转移复杂度也是 \(O(nm^2)\) 的,但是第一种情况只要记录前一位是否含 \(1\) 即可优化为 \(O(nm)\)。总体时间复杂度 \(O(nm)\)

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
#define eb(x) emplace_back(x)
#define pb(x) push_back(x)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using pi=pair<int,int>;
bool dp[200005][10],hv[200005];
int n,m;
char a[200005],b[10];
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n>>m>>a+1>>b+1;dp[0][0]=1;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(a[i]==b[j]){dp[i][j]|=dp[i-1][j-1];dp[i][j]|=dp[i-1][m];if(j==1)dp[i][j]|=hv[i-1];}hv[i]|=dp[i][j];}}if(dp[n][m])cout<<"Yes";else cout<<"No";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/866813.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在Lazarus下的Free Pascal编程教程——打造有智能感知的用户设置操作界面

0.前言 我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”和“…

基于CNN卷积神经网络的金融数据预测matlab仿真,对比BP,RBF,LSTM

1.程序功能描述 基于CNN卷积神经网络的金融数据预测matlab仿真,对比BP神经网络,RBF神经网络,LSTM网络.对比预测结果和预测误差。 2.测试软件版本以及运行结果展示MATLAB2022A版本运行 3.核心程序for i = 1:floor(length(data1)/5);p1w(5*i-4:5*i,1) = [p1(i,1);p1(i,1);…

G1原理—2.G1是如何提升分配对象效率

大纲 1.G1的对象分配原理是怎样的 2.深入分析TLAB机制原理 3.借助TLAB分配对象的实现原理是什么 4.什么是快速分配 + 什么是慢速分配 5.大对象分配的过程 + 与TLAB的关系 6.救命的稻草—JVM的最终分配尝试G1如何分配对象+TLAB机制+分区协调机制 G1设计了一套TLAB机制+快速分配机…

《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下

《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下@目录1.Docker简介1.1Docker是什么1.1.1问题:为什么会有docker出现?1.1.2Docker理念1.1.3一句话1.2容器与虚拟机比较1.2.1容器发展简史1.2.2传统虚拟机技术1.2.3容器虚拟化技术1.2.4对比…

redis的zset | 跳表

redis的zset有两种数据结构:跳表和压缩列表 压缩列表除了一般元素外还包括列表长度、列表元素个数、尾部偏移量、列表结束标识等。在zset的长度较小的时候,用这个比较好 什么是跳表 跳表是在链表的基础上,增加了多层索引,利用多级索引的跳转快速实现查询。每次新增一个节点…

Python Matplotlib 教程- Matplotlib 如何进行数据点标记

Python Matplotlib 数据点标记 在数据可视化中,数据点标记是非常重要的部分。无论是绘制折线图、散点图还是柱状图,清晰地标记关键数据点可以帮助观众快速理解图表的核心信息。本篇文章将详细介绍如何在 Python 的 Matplotlib 中实现数据点标记,从基础使用到高级自定义,帮助…

P1803 凌乱的yyy / 线段覆盖

P1803 凌乱的yyy / 线段覆盖 题目 现在各大 oj 上有 \(n\) 个比赛,每个比赛的开始、结束的时间点是知道的。 yyy 认为,参加越多的比赛,noip 就能考的越好(假的)。 所以,他想知道他最多能参加几个比赛。 由于 yyy 是蒟蒻,如果要参加一个比赛必须善始善终,而且不能同时参…

P1325 雷达安装

P1325 雷达安装 题目 假设海岸线是一条无限延伸的直线。它的一侧是陆地,另一侧是海洋。每一座小岛是在海面上的一个点。雷达必须安装在陆地上(包括海岸线),并且每个雷达都有相同的扫描范围 \(d\)。你的任务是建立尽量少的雷达站,使所有小岛都在扫描范围之内。 数据使用笛卡…

第4章 类型设计准则

第4章 类型设计准则​DO​:类应该由一组定义明确、相互关联的成员组成。 一个类,如果能用一句话描述清楚它的用途,那么它的设计是优秀的。1 类型(class、struct)和 namespace​DO​:namespace 用于组织类,通过 namespace 将相关功能按层次铺开,但不要有过深的层次、过多…

BurpSuite实操之代理功能

一、代理原理Burp Suite代理工具是以拦截代理的方式,拦截所有通过代理的网络流量,如客户端的请求数据、服务器端的返回信息等。通过拦截,Burp Suite以中间人的方式,可以对客户端请求数据、服务端返回做各种处理,以达到安全评估测试的目的。在日常工作中,我们最常用的web客…

window11安装安卓子系统,畅玩安卓软件

在Windows 11刚推出时,微软便宣称该操作系统中可以直接安装运行安卓APK应用程序,如同Android虚拟机一样,不过是要实现这一功能,我们必须在Windows 11中单独安装Windows 11安卓子系统,这里说明一下其标准的名称为:适用于 Android™️ 的 Windows 子系统(Windows Subsyste…

Python + Appium 自动化操作微信入门(超详细)

Appium是一个开源的自动化测试工具,支持 Android、iOS 平台上的原生应用,支持 Java、Python、PHP 等多种语言。Appium是一个开源的自动化测试工具,支持 Android、iOS 平台上的原生应用,支持 Java、Python、PHP 等多种语言。 Appium 封装了 Selenium,能够为用户提供所有常见…