codeforces 1426F,初学者也能做,div3的最难题
大家好,欢迎阅读codeforces专题。
今天选择的题目是Div3比赛的最后一题,也是最难的一道题。选这道题的主要原因是帮助大家建立信心,因为有些小伙伴给我反应说之前选择的题目有些难了,觉得自己可能应付不了codeforces的题目。所以今天特地选了Div3比赛当中的最难题来给大家一点信心。
Div3比赛是难度最低的比赛,面向的是算法的初学者,非常适合大家作为入门练习。由于是最后一道题,所以这题的通过人数不是很多,大概是530人。但是这题并不很难,我感觉大约和我们Div2中的C题相当。
链接:https://codeforces.com/contest/1426/problem/F
废话不多说了,让我们直接看题吧。
题意
给定一个只有abc和?的字符串,其中的?可以被任意替换成a、b或者c。我们假设?一共有k个,这样我们一共可以得到个不同的字符串。
要求所有这些字符串当中拥有的abc子序列的个数,子序列是指原串在不改变元素相对顺序的情况下通过删除元素得到的子集。比如说baacbc拥有两个abc的子序列,分别是下标组合(2,5,6)和(3,5,6)。
由于最终的数量可能会很大,要求这个结果对取模。
样例
输入一共有两行,第一行给定一个整数n(),表示字符串的长度。第二行输入长度为n的字符串,要求返回abc子序列的个数。
对于第一个样例的解释:
题解
这题看起来比较复杂,想要直接想出解法来正面攻破还是不太容易的。所以我们先把一些条件放一放,先从最简单的思路入手。
最简情况
首先我们需要解决一个问题,就是当不存在?的时候,我们如何求出abc子序列的个数呢?比如acabac,我们怎么求出其中abc子序列的数量呢?答案是2,这个2是怎么来的呢?
因为要保证b出现在a的后面,c出现在b的后面,我们当然可以直接用三重循环去枚举所有的组合,但这显然不是最好的方法。我们仔细想一下,这是一个有限制的组合问题,很容易发现每一个字母b都可以和它之前的所有a组成ab的配对,同样每个字母c也可以和之前的每个序列ab组成abc的子序列。
那么我们可以使用动态规划的思路来求解,我们用三个变量d[0], d[1], d[2],分别维护a、ab和abc串的数量。当我们遇到a的时候,d[0]加1,遇到b的时候呢?d[1]加1吗?显然不对,因为b可以和之前的每一个a都组成ab,所以d[1]应该加的不是1而是d[0]。同样,遇到c的时候,也一样,d[2]应该加上d[1]。
这样我们就可以求出在没有?时满足条件的子序列的数量了。
d = [0, 0, 0]
for i in range(n):
if s[i] == 'a':
d[0] += 1
elif s[1] == 'b':
d[1] += d[0]
else:
d[2] += d[1]
进阶使用
现在我们已经解决了没有?出现时的情况,那么加上?的话应该怎么办呢?
我们进一步来分析,对于每一个?来说它其实都有三种选择。比如a?c,展开之后会有aac,abc,acc这三种情况。那么我们能不能在遇到?的时候把这三种情况全部都考虑进去呢?
当我们遇到?的时候,我们把d数组拷贝成三份,分别用来存储?=a, ?=b 和 ?=c的情况。我们先把数组d拷贝成d1、d2和d3。我们用这三个数组代表?取三种不同取值的情况,最后再把它们合并到一起,变成新的数组d_new。
因为d1, d2和d3其实就是d,所以我们把它们最后整合在一起之后依然可以用d来表示。
到这里都没有问题对吧,其实这里藏了一个trick。这个trick非常隐蔽,很难发现。就是我们在?=a的情况下,我们这里d1[0] += 1其实是不对的,我们要加的不是1。我们来举一个例子就明白了,比如a??c。
在这个字符串当中我们存在两个?,对于第一个?而言,它是a的时候d[0] += 1这没有问题。但是当遇到第二个?的时候问题就来了,对于第一个问号等于a的情况而言,由于第二个问号有三种取值,那么带来的a的数量其实应该是3,而不是1。我们只加了1就是错误的。我们也可以反过来理解,对于第一个问号,我们整合了三种可能性。当我们第二个问号设置为a的时候,其实是背后是第一个问号带来的3种可能,所以这里要加的就不是1而是3。如果我们有3个问号呢?第三个问号显然加的就是9了。也就是说对于第k个问号而言,。
这个trick注意到了,那么AC也就是顺理成章的事了。
n = int(input())
s = input()
ret = 0
Mod = int(1e9+7)
dp = [0, 0, 0]
cnt = 1
for i in range(n):
if s[i] == 'a':
dp[0] += cnt
elif s[i] == 'b':
dp[1] += dp[0]
elif s[i] == 'c':
dp[2] += dp[1]
else:
dp[2] = (3 * dp[2] + dp[1]) % Mod
dp[1] = (3 * dp[1] + dp[0]) % Mod
dp[0] = (3 * dp[0] + cnt) % Mod
cnt = (cnt * 3) % Mod
print(dp[2] % Mod)
今天选择的是div3比赛当中通过人数最少,也就是最难的一题。但我们做下来会发现其实也就用到了最基础的动态规划的思想,虽然不容易想到解,但是难度其实还可以。
所以如果你想要提升自己的算法能力,但是又担心题目太难自己无法胜任的话,可以考虑做一做div3的一些比赛。相信我不会太难的。
今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发)

codeforces 1426F,初学者也能做,div3的最难题的更多相关文章
- Codeforces Round #239(Div. 2) 做后扯淡玩
今天补了下 cf 239div2 顿时信心再度受挫 老子几乎已经木有时间了啊 坐着等死的命.哎!!! 到现在还只能做大众题,打铁都不行. 每次D题都是有思路敲错,尼玛不带这么坑爹的. 哎!不写了,写这 ...
- 初学者用js做的计算题
1.苹果3元一个,鸭梨2元一个,桃子1元一个.现在想用200元买100个水果,在控制台中打印出来. var apple = 0; //苹果 var pear = 0; //梨 var peach = ...
- CodeForces 1426F Number of Subsequences
题意 给定一个长度为 \(n\) 的串,只包含 abc 和通配符.通配符可以替换 abc 的一个.求所有得到的字符串中子序列 abc 出现的次数,对 \(10^9+7\) 取模. \(\texttt{ ...
- Codeforces Round #575 (Div. 3) 昨天的div3 补题
Codeforces Round #575 (Div. 3) 这个div3打的太差了,心态都崩了. B. Odd Sum Segments B 题我就想了很久,这个题目我是找的奇数的个数,因为奇数想分 ...
- 刷题记录:Codeforces Round #724 (Div. 2)
Codeforces Round #724 (Div. 2) 20210713.网址:https://codeforces.com/contest/1536. div2明显比div3难多了啊-只做了前 ...
- 刷题记录:Codeforces Round #719 (Div. 3)
Codeforces Round #719 (Div. 3) 20210703.网址:https://codeforces.com/contest/1520. 没错,我是个做div3的蒟蒻-- A 大 ...
- 初学者--bootstrap(五)JavaScript插件(上)----在路上(6)
jQuery 插件为 Bootstrap 的组件赋予了“生命”.可以简单地一次性引入所有插件,或者逐个引入到你的页面中. 一:首先要确认的是,单个还是全部引入: JavaScript 插件可以单个引入 ...
- Codeforces Round #279 (Div. 2) ABCDE
Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems # Name A Team Olympiad standard input/outpu ...
- [置顶] Codeforces Round #198 (Div. 1)(A,B,C,D)
http://codeforces.com/contest/341 赛后做的虚拟比赛,40分钟出了3题,RP爆发. A计数问题 我们可以对每对分析,分别对每对<a, b>(a走到b)进行统 ...
随机推荐
- BERT模型详解
1 简介 BERT全称Bidirectional Enoceder Representations from Transformers,即双向的Transformers的Encoder.是谷歌于201 ...
- 经典剪枝算法的例题——Sticks详细注释版
这题听说是道十分经典的剪枝算的题目,不要问我剪枝是什么,我也不知道,反正我只知道用到了深度搜索 我参考了好多资料才悟懂,然后我发现网上的那些大神原理讲的很明白,但代码没多少注释,看的很懵X,于是我抄起 ...
- MVC查询
前言 最近没什么好写的,所以写个查询来巩固一下知识 HTML @{ Layout = null; } <!DOCTYPE html> <html> <head> & ...
- poj1050 To the Max(降维dp)
To the Max Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 49351 Accepted: 26142 Desc ...
- 类型转化 - js中的骚操作
Number Number() 把字符串数字转化成数字类型,布尔类型也可以转化 parseInt parseInt() 字符串数字转化成数字类型,当布尔类型不可以(NaN),但该函数可以把数字开头的数 ...
- GridView使用SimpleAdapter
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app=&q ...
- Javascript中this作用域以及bind方法的重写
这是一个最近遇到的笔试题,出于尊重,不会说出该公司的名字,源于自身比较少,笔试题是将bind方法用ES3重写,使用bind这个方法,导致一时半会懵了,只记得bind可以改变this的作用域. 作为查漏 ...
- 排名靠前的几个JS框架发展趋势和前景
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://blog.bitsrc.io/top-5-javascript-frameworks ...
- 一个Task.Factory.StartNew的错误用法
同事写了这样一段代码: FactoryStartNew类: using System; using System.Collections.Generic; using System.Linq; usi ...
- 嵌入式linux和stm32嵌入式开发这两者之间有什么关联性
对于更开始入坑的同学,可能也像我一样搞不清楚两者的区别与联系.现在结合知乎网上的相关资料发一篇文章来具体分析. 基于STM32的开发属于微控制器开发领域,主要开发工具是keil或IAR,这种开发更准确 ...