题解 CF296B 【Yaroslav and Two Strings】
题目
题目大意
如果两个只包含数字且长度为 \(n\) 的字符串 \(s\) 和 \(w\) 存在两个数字 \(1≤i,j≤n\),使得 \(s_i<w_i,s_j>w_j\) ,则称 \(s\) 和 \(w\) 是不可比的。现在给定两个包含数字和问号且长度为 \(n\) 的字符串,问有多少种方案使得将所有问号替换成 \(0\) 到 \(9\) 的数字后两个字符串是不可比的?
思路
分析
DP 题, 我们注意到,只要有一对这样的数就可以满足条件,而等于是不属于判断情况的,因此我们要单独记一个状态。
状态
f[i][k]: 当在第 $i$ 位时,第 $k$ 种情况的方案数。
以下: j < i
k = 0 : 前面只出现了 s[j] < w[j] 的情况,并没有 s[j] > w[j] ,即 s[j] <= w[j]
k = 1 : 前面 s[j] < w[j] , s[j] > w[j]
k = 2 : 前面只出现了 s[j] > w[j] 的情况,并没有 s[j] < w[j] ,即 s[j] >= w[j]
k = 3 : 前面只有 s[j] == w[j] 情况
转移
我们要对每一位考虑该位上填每个数字的情况。
对于已经确定数字的位,我们要只要对该数字讨论。
如果有'?',我们要枚举 1~9 进行转移。
感觉有点像数位DP?
初始状态
f[0][3] = 1
代码
按照各种状态进行转移即可,代码量有点大。
当然,也有一种代码量小的解法,可以预先算出每种情况转移,就不必枚举。
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
const int MAXN = 1e5+10;
const ll mod = 1e9+7;
int n;
ll f[MAXN][4];
char s[MAXN],w[MAXN];
int main (){
scanf("%d",&n);
scanf("%s",s+1);
scanf("%s",w+1);
f[0][0] = f[0][1] =f[0][2] = 0;
f[0][3] = 1;
for(int i = 1;i <= n;i++){
if(s[i] != '?' &&w[i] != '?'){
if(s[i] > w[i]) {
f[i][0] = 0;
f[i][1] = f[i-1][0] + f[i-1][1];
f[i][2] = f[i-1][2] + f[i-1][3];
f[i][3] = 0;
} else if(s[i] == w[i]){
f[i][0] = f[i-1][0];
f[i][1] = f[i-1][1];
f[i][2] = f[i-1][2];
f[i][3] = f[i-1][3];
} else{
f[i][0] = f[i-1][0] + f[i-1][3];
f[i][1] = f[i-1][2] + f[i-1][1];
f[i][2] = 0;
f[i][3] = 0;
}
} else if(s[i] == '?' && w[i] != '?'){
for(int j = '0';j < w[i] ;j++){
f[i][0] += f[i-1][0] + f[i-1][3];
f[i][1] += f[i-1][1] + f[i-1][2];
f[i][2] += 0;
}
f[i][0] += f[i-1][0];
f[i][1] += f[i-1][1];
f[i][2] += f[i-1][2];
f[i][3] += f[i-1][3];
for(int j = w[i] + 1;j <= '9';j++){
f[i][1] += f[i-1][0] + f[i-1][1];
f[i][2] += f[i-1][2] + f[i-1][3];
}
} else if(s[i] != '?' && w[i] == '?'){
for(int j = '0' ;j < s[i] ;j++){
f[i][1] += f[i-1][0] + f[i-1][1];
f[i][2] += f[i-1][2] + f[i-1][3];
}
f[i][0] += f[i-1][0];
f[i][1] += f[i-1][1];
f[i][2] += f[i-1][2];
f[i][3] += f[i-1][3];
for(int j = s[i] +1;j <= '9' ;j++){
f[i][0] += f[i-1][0] + f[i-1][3];
f[i][1] += f[i-1][1] + f[i-1][2];
}
} else{
for(int j = 0;j < 10;j++){
for(int k = 0;k < 10;k++){
if(j<k){
f[i][0] += (f[i-1][0] + f[i-1][3])%mod;
f[i][1] += (f[i-1][1] + f[i-1][2])%mod;
} else if(j == k){
f[i][0] += f[i-1][0];
f[i][1] += f[i-1][1];
f[i][2] += f[i-1][2];
f[i][3] += f[i-1][3];
} else{
f[i][1] += (f[i-1][0] + f[i-1][1])%mod;
f[i][2] += (f[i-1][2] + f[i-1][3])%mod;
}
f[i][0] %= mod;
f[i][1] %= mod;
f[i][2] %= mod;
}
}
}
f[i][0] %= mod;
f[i][1] %= mod;
f[i][2] %= mod;
}
printf("%d",f[n][1] % mod);
return 0;
}
题解 CF296B 【Yaroslav and Two Strings】的更多相关文章
- Codeforces Round #179 (Div. 2) B. Yaroslav and Two Strings (容斥原理)
题目链接 Description Yaroslav thinks that two strings s and w, consisting of digits and having length n ...
- 最长重复字符串题解 golang
最长重复字符串题解 package main import ( "fmt" "strings" ) type Index map[int]int type Co ...
- Codeforces Round #179 (Div. 1 + Div. 2)
A. Yaroslav and Permutations 值相同的个数不能超过\(\lfloor \frac{n + 1}{2} \rfloor\). B. Yaroslav and Two Stri ...
- 题解-ARC058D Iroha Loves Strings
题面 ARC058D Iroha Loves Strings 给定 \(n\) 个字符串,从中选出若干个按给出顺序连接起来,总长等于 \(m\),求字典序最小的,保证有解. 数据范围:\(1\le n ...
- 题解-Reachable Strings
题解-Reachable Strings 前置知识: \(\texttt{Hash}\) Reachable Strings 给一个长度为 \(n\) 的 \(\texttt{01}\) 串 \(s\ ...
- [LeetCode]题解(python):043-Multiply Strings
题目来源 https://leetcode.com/problems/multiply-strings/ Given two numbers represented as strings, retur ...
- 【题解】Power Strings
题目描述 给定若干个长度小于等于10^6的字符串,询问每个字符串最多由多少个相同的子串重复连接而成.如:ababab,最多由3个ab连接而成. 输入输出格式 输入格式 若干行,每行一个字符串. 当读入 ...
- Power Strings[poj2406]题解
Power Strings Description - Given two strings a and b we define ab to be their concatenation. For ex ...
- CF1320 Div1 D.Reachable Strings 题解
题目大意 给定一个长为\(n\)的01串\(S\),每次你可以对一个串的三个连续位置做:\(011 \rightarrow 110\),\(110 \rightarrow 011\)的操作. 有\(q ...
随机推荐
- redis编译报错总结
redis编译报错总结: 1.不能编译没有GCC 编译工具安装报错:问题1:make时可能会报如下错误cc -c -std=c99 -pedantic -O2 -Wall -W -g -rdyna ...
- mybatis读写分离
mybatis读写分离实现方式有很多种,当然如果没有太过复杂的处理,可以使用阿里云数据库自带的读写分离连接,那样会更加简洁.本文主要对mybatis实现读写分离.主要的实现方式有一下四种: 方案1 通 ...
- ElasticSearch--validate验证搜索语句是否合法或者存在语法错误
GET /accounts/person/_validate/query?explain { "query":{ "match": { "user&q ...
- 多线程集成设计模式--future模式
多线程开发可以更好的发挥多核cpu性能,常用的多线程设计模式有:Future.Master-Worker.Guard Susperionsion 一.什么是Future模型: 该模型是将异步请求和代理 ...
- IDEA创建SpringBoot的多模块项目教程
最近在写一个多模块的SpringBoot项目,基于过程总了一些总结,故把SpringBoot多个模块的项目创建记录下来. 首先,先建立一个父工程: (1)在IDEA工具栏选择File->New- ...
- 【Flutter实战】自定义滚动条
老孟导读:[Flutter实战]系列文章地址:http://laomengit.com/guide/introduction/mobile_system.html 默认情况下,Flutter 的滚动组 ...
- [开源]eCharts配置简化包OptionCreator[typescript版]
eCharts存在问题 配置eCharts的option,对于大部分的开发者来说,复杂情况下是一件繁琐的事情.为什么繁琐,大致有以下这些原因 大小写敏感:在没有IDE的智能提示下,很容易写错,而且即使 ...
- 面试WEB前端如何才能通过?
从事web前端工作七年时间,因为一直是非常热爱编程的,从小就有兴趣,大学就是学计算机的,技术应该比一般同龄的都要好一些,今天我想给大家讲述一下,目前想要做web前端开发,面试成功应该如何去学习,要具备 ...
- CSS3 nth-child的使用,详解css中nth的作用,以及nth-child的兼容写法
:nth-child是css3的一个比较常用的选择器.它用于匹配属于其父元素中的子元素,不论元素的类型. 它的参数可以是数字.关键词或公式.下面讲介绍它的使用方法, nth-child的使用 html ...
- Java基础笔记01-02-03-04
一.今日内容介绍 1.Java开发环境搭建 2.HelloWorld案例 3.注释.关键字.标识符 4.数据(数据类型.常量) 01java语言概述 * A: java语言概述 * a: Java是s ...