题目

传送门

题目大意

如果两个只包含数字且长度为 \(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】的更多相关文章

  1. 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  ...

  2. 最长重复字符串题解 golang

    最长重复字符串题解 package main import ( "fmt" "strings" ) type Index map[int]int type Co ...

  3. Codeforces Round #179 (Div. 1 + Div. 2)

    A. Yaroslav and Permutations 值相同的个数不能超过\(\lfloor \frac{n + 1}{2} \rfloor\). B. Yaroslav and Two Stri ...

  4. 题解-ARC058D Iroha Loves Strings

    题面 ARC058D Iroha Loves Strings 给定 \(n\) 个字符串,从中选出若干个按给出顺序连接起来,总长等于 \(m\),求字典序最小的,保证有解. 数据范围:\(1\le n ...

  5. 题解-Reachable Strings

    题解-Reachable Strings 前置知识: \(\texttt{Hash}\) Reachable Strings 给一个长度为 \(n\) 的 \(\texttt{01}\) 串 \(s\ ...

  6. [LeetCode]题解(python):043-Multiply Strings

    题目来源 https://leetcode.com/problems/multiply-strings/ Given two numbers represented as strings, retur ...

  7. 【题解】Power Strings

    题目描述 给定若干个长度小于等于10^6的字符串,询问每个字符串最多由多少个相同的子串重复连接而成.如:ababab,最多由3个ab连接而成. 输入输出格式 输入格式 若干行,每行一个字符串. 当读入 ...

  8. Power Strings[poj2406]题解

    Power Strings Description - Given two strings a and b we define ab to be their concatenation. For ex ...

  9. CF1320 Div1 D.Reachable Strings 题解

    题目大意 给定一个长为\(n\)的01串\(S\),每次你可以对一个串的三个连续位置做:\(011 \rightarrow 110\),\(110 \rightarrow 011\)的操作. 有\(q ...

随机推荐

  1. Jmeter之仿真高并发测试-集合点

    场景: 大家在使用Jmeter测试的时候应该发现了, (1)线程启动了就会直接发送测试请求:--如果要模拟在一瞬间高并发量测试的时候,需要调高线程数量,这很耗测试机器的性能,往往无法支持较大的并发数, ...

  2. SpringCloud教程第4篇:Hystrix(F版本)

    在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用.为了保证其高可用,单个服务 ...

  3. elasticSearch插件metricbeat收集nginx的度量指标

    ngx_http_stub_status_module模块是Nginx中用来统计Nginx服务所接收和处理的请求数量,只要在编译安装Nginx的时候加上参数--with-http_stub_statu ...

  4. SDL软件安全读书笔记(一)

    # 如何应对当前的全球网络安全威胁? 开发安全漏洞尽可能少的软件,应该着眼于源头安全. 边界安全盒深度防御是重要的安全手段,但软件自身的安全是安全防护的第一关. 即使软件源头存在较少的漏洞,这些漏洞也 ...

  5. IntelliJ IDEA安装配置、搭建Spring MVC

    安装前必备软件: 1.jdk1.8.0_144安装包 2.IntelliJ IDEA 2016.1.1(64) 3.Tomcat安装包 4.Mysql.MySQL-JDBC驱动安装包 5.Jetbra ...

  6. dart快速入门教程 (3)

    3.运算符 运算符本质上就是代表某运算规则的符号,例如: + ,这个符号,代表着数学运算里面的加法,按照加法法则进行运算即可,同理,学习运算符就是掌握这些规则而已 3.1.算术运算符 算术运算符主要包 ...

  7. vue基础入门(2.3)

    2.3.样式绑定 2.3.1.绑定class样式 1.绑定单个class <!DOCTYPE html> <html lang="en"> <head ...

  8. 只需几行 JavaScript 代码,网页瞬间有气质了!

    最近在网上闲逛,发现一个特别好玩的 JavaScript 库,叫 RoughNotation.干嘛用的呢?就是在网页上给文字加标注,比如下划线.方框.高亮文字背景等,不过是手写风格的!截图给大家感受下 ...

  9. Typography convention

    1 h1 Chapter title centered,number three in bold,used ##. 1.1 h2 The chapter is a section, and the s ...

  10. sorted 函数及小练习

    python 中sorted函数 sorted() 函数对所有可迭代的对象进行排序操作. sorted 语法: sorted(iterable[, cmp[, key[, reverse]]]) 参数 ...