大家好,欢迎阅读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的最难题的更多相关文章

  1. Codeforces Round #239(Div. 2) 做后扯淡玩

    今天补了下 cf 239div2 顿时信心再度受挫 老子几乎已经木有时间了啊 坐着等死的命.哎!!! 到现在还只能做大众题,打铁都不行. 每次D题都是有思路敲错,尼玛不带这么坑爹的. 哎!不写了,写这 ...

  2. 初学者用js做的计算题

    1.苹果3元一个,鸭梨2元一个,桃子1元一个.现在想用200元买100个水果,在控制台中打印出来. var apple = 0; //苹果 var pear = 0; //梨 var peach = ...

  3. CodeForces 1426F Number of Subsequences

    题意 给定一个长度为 \(n\) 的串,只包含 abc 和通配符.通配符可以替换 abc 的一个.求所有得到的字符串中子序列 abc 出现的次数,对 \(10^9+7\) 取模. \(\texttt{ ...

  4. Codeforces Round #575 (Div. 3) 昨天的div3 补题

    Codeforces Round #575 (Div. 3) 这个div3打的太差了,心态都崩了. B. Odd Sum Segments B 题我就想了很久,这个题目我是找的奇数的个数,因为奇数想分 ...

  5. 刷题记录:Codeforces Round #724 (Div. 2)

    Codeforces Round #724 (Div. 2) 20210713.网址:https://codeforces.com/contest/1536. div2明显比div3难多了啊-只做了前 ...

  6. 刷题记录:Codeforces Round #719 (Div. 3)

    Codeforces Round #719 (Div. 3) 20210703.网址:https://codeforces.com/contest/1520. 没错,我是个做div3的蒟蒻-- A 大 ...

  7. 初学者--bootstrap(五)JavaScript插件(上)----在路上(6)

    jQuery 插件为 Bootstrap 的组件赋予了“生命”.可以简单地一次性引入所有插件,或者逐个引入到你的页面中. 一:首先要确认的是,单个还是全部引入: JavaScript 插件可以单个引入 ...

  8. Codeforces Round #279 (Div. 2) ABCDE

    Codeforces Round #279 (Div. 2) 做得我都变绿了! Problems     # Name     A Team Olympiad standard input/outpu ...

  9. [置顶] Codeforces Round #198 (Div. 1)(A,B,C,D)

    http://codeforces.com/contest/341 赛后做的虚拟比赛,40分钟出了3题,RP爆发. A计数问题 我们可以对每对分析,分别对每对<a, b>(a走到b)进行统 ...

随机推荐

  1. .Net Core 3.0 MVC 中使用 SqlSugar ORM框架

    介绍 SqlSugar 是一款简单易用的ORM ,在国内市场占有率也比较高, 在今年10月份官网改版后  提供了完整的服务,让您的项目没有后顾之忧 下载地址 :https://github.com/s ...

  2. JS实现鼠标移入水波效果

    前言 最近比较沉迷JS,所以我现在来做个鼠标的交互效果 HTML <div style="border-radius;position:relative;width:800px;hei ...

  3. 12天搞定Python,基础语法(上)

    不知你是否见过建楼房的过程,没有的话,找个时间去瞧一瞧,看一看.看过之后,你就会明白.建楼房,只有打好地基之后,才能在砌墙,建的楼层越高,打的地基就越深. 学编程也一样,要想得心应手的应用,得先打好地 ...

  4. Java之HttpClient调用WebService接口发送短信源码实战

    摘要 Java之HttpClient调用WebService接口发送短信源码实战 一:接口文档 二:WSDL 三:HttpClient方法 HttpClient方法一 HttpClient方法二 Ht ...

  5. Mybatis初学经验----------------(2)

    至于myBatis的配置,上篇文章中有,就不说了.今天谈谈myBatis编写Dao层时的用法. 传统Dao层代码需求 1.在Dao层实现类中,存在大量的模板方法,能否提取模板方法,减少我们的工作量. ...

  6. 看完这篇 final、finally 和 finalize 和面试官扯皮就没问题了

    我把自己以往的文章汇总成为了 Github ,欢迎各位大佬 star https://github.com/crisxuan/bestJavaer 已提交此篇文章 final 是 Java 中的关键字 ...

  7. NB-IOT的应用场景有哪些

    虽然抄表.停车.井盖监测等应用是最为常见的示范,但若低功耗广域网络仅限于这几个领域,则整个产业的规模就显得太小了.实际上,经过近两年的探索,目前示范应用的数量已有数十个,分布在各行各业,带来了大量的机 ...

  8. 震惊!你还不知道SpringBoot真正的启动引导类

    引言 SpringBoot项目中的启动类,一般都是XXApplication,例如「StatsApplication」,「UnionApplication」. 每个项目的启动类名称都不一样.但是它的启 ...

  9. Java基础系列-单例的7种写法

    原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755322.html 一.概述 Java中单例有7种写法,这个是在面试中经常被问到的内容,而且有时候 ...

  10. 20181301刘天宁 MyOD

    一.题目要求: 1.复习c文件处理内容编写myod.c 2.用myod XXX实现Linux下od -tx -tc XXX的功能 3.main与其他分开,制作静态库和动态库 4.编写Makefile ...