G-subsequence 1

题意

给你两个字符串\(s、t\),问\(s\)中有多少个子序列能大于\(t\)。

思路

令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长度

  1. \(len1 > lent\):枚举每一位,如果当前为不为\(0\)那么它后面的位置可以随意取,\(num = num + \binom{k}{len-1}、k\)是当前位到\(s\)的末尾剩下的位数
  2. \(len1 = lent\):暴力\(n^3\)肯定超时,所以要用\(dp\)优化

    \(dp[i][j][1]\):\(s[j]\)作为第\(i\)个数大于\(t[1\)~\(i]\)前缀的个数

    \(dp[i][j][2]\):\(s[j]\)作为第\(i\)个数等于\(t[1\)~\(i]\)前缀的个数

    • \(s[j] > t[i]\):\(dp[i][j][1] = dp[i-1][1\) ~ \(j-1][1]+dp[i-1][1\) ~ \(j-1][2]\)、\(dp[i][j][2] = 0\)

    • \(s[j] = t[i]\):\(dp[i][j][1] = dp[i-1][1\) ~ \(j-1]\)、\(dp[i][j][2] = dp[i-1][1\) ~ \(j-1][2]\)

    • \(s[j] < t[i]\):\(dp[i][j][1] = dp[i-1][1\) ~ \(j-1]\)、\(dp[i][j][2] = 0\)

  3. 用一个前缀和维护一下\(dp[i-1]\)的前缀,就可以把\(dp\)优化到\(n^2\)了

AC 代码

#include<bits/stdc++.h>
#define mes(a, b) memset(a, b, sizeof a)
using namespace std;
typedef long long ll;
const int maxn = 3e3+10;
const ll mod = 998244353;
struct A{
int num[3][maxn];
void init(){
mes(num, 0);
}
}a, b;
char s[maxn], t[maxn];
ll dp[maxn][maxn][3];
ll C[maxn][maxn];
void init(){ //组合数打表
C[0][0] = C[1][0] = C[1][1] = 1;
for(int i = 2; i < maxn;i++){
for(int j = 0; j <= i; j++){
C[i][j] = j==0?1:C[i-1][j-1]+C[i-1][j];
C[i][j] %= mod;
}
}
} int main(){
int T, n, m;
scanf("%d", &T);
init();
while(T--){
scanf("%d%d", &n, &m);
scanf("%s%s", s+1, t+1);
ll ans = 0;
a.init(); //表示dp[i-1]的前缀和
b.init(); //表示dp[i]的前缀和
for(int i = 1; i <= n-m; i++){
if(s[i] != '0')
for(int j = m; j <= n-i; j++){
ans = (ans + C[n-i][j])%mod;
}
}
for(int i = 0; i <= n; i++){ //初始化
a.num[2][i] = 1;
}
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
if(s[j] > t[i]){
dp[i][j][1] = (a.num[1][j-1]+a.num[2][j-1])%mod;
dp[i][j][2] = 0;
}
else if(s[j] == t[i]){
dp[i][j][1] = a.num[1][j-1];
dp[i][j][2] = a.num[2][j-1];
}
else{
dp[i][j][1] = a.num[1][j-1];
dp[i][j][2] = 0;
}
b.num[1][j] = (b.num[1][j-1] + dp[i][j][1])%mod;
b.num[2][j] = (b.num[2][j-1] + dp[i][j][2])%mod;
}
swap(a, b);
b.num[1][0] = b.num[2][0] = 0;
}
ans = (ans + a.num[1][n])%mod;
printf("%lld\n", ans);
}
return 0;
}

2019牛客多校第五场G-subsequence 1 DP的更多相关文章

  1. 2019牛客多校第五场 G subsequence 1 dp+组合数学

    subsequence 1 题意 给出两个数字串s,t,求s的子序列中在数值上大于t串的数量 分析 数字大于另一个数字,要么位数多,要么位数相同,字典序大,位数多可以很方便地用组合数学来解决,所以只剩 ...

  2. 2019牛客多校第五场H - subsequence 2 拓扑

    H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...

  3. 牛客多校第五场 G subsequence 1 最长公共子序列/组合数

    题意: 给定两个由数字组成的序列s,t,找出s所有数值大于t的子序列.注意不是字典序大. 题解: 首先特判s比t短或一样长的情况. 当s比t长时,直接用组合数计算s不以0开头的,长度大于t的所有子序列 ...

  4. 2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂

    理论部分 二次剩余 在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数. 当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称 ...

  5. 2019牛客多校第五场generator2——BSGS&&手写Hash

    题目 几乎原题 BZOJ3122题解 分析 先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法. 在标准的BSGS中,内 ...

  6. 2019牛客多校第五场F maximum clique 1 最大独立集

    题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...

  7. 2019牛客多校第五场 B - generator 1 矩阵快速幂+十倍增+二进制倍增优化

    B - generator 1 题意 给你\(x_{0}.x_{1}.a.b.b.mod\),根据\(x_{i} = a*x_{i-1} + b*x_{i-2}\)求出\(x_{n}\) 思路 一般看 ...

  8. 2019牛客多校第五场B-generator 1(矩阵快速幂)

    generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...

  9. 2019 牛客多校第五场 B generator 1

    题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...

随机推荐

  1. [CSP-S模拟测试]:mine(DP)

    题目描述 有一个$1$维的扫雷游戏,每个格子用$*$表示有雷,用$0/1/2$表示无雷并且相邻格子中有$0/1/2$个雷.给定一个仅包含$?$.$*$.$0$.$1$.$2$的字符串$s$,问有多少种 ...

  2. JDK1.8 动态代理机制及源码解析

    动态代理 a) jdk 动态代理 Proxy, 核心思想:通过实现被代理类的所有接口,生成一个字节码文件后构造一个代理对象,通过持有反射构造被代理类的一个实例,再通过invoke反射调用被代理类实例的 ...

  3. Bootstrap Date Range Picker

    var optionSet1 = { startDate: moment().subtract(29, 'days'), endDate: moment(), minDate: '12/21/2012 ...

  4. Python 多进程异常处理

    前言 最近项目用到了Python作为网站的前端,使用的框架是基于线程池的Cherrypy,但是前端依然有一些比较‘重’的模块.由于python的多线程无法很好的利用多核的性质,所以觉得把这些比较‘重’ ...

  5. Linux操作系统(四)_部署MySQL

    一.部署过程 1.当前服务器的内核版本和发行版本 cat /etc/issue uname -a 2.检查系统有没有自带mysql,并卸载自带版本 yum list installed | grep ...

  6. 《JavaScript DOM 编程艺术》学习成果

    (在线演示地址)[http://thqy39.github.io/works/03.Js%20DOM%20website/index.html]

  7. 【awk】 处理多个文件

    处理多个文件: 1. 可以在代码中指定读取某个文件, 其他的用命令行输入           while ( geline < "file.txt" > 0 ) {   ...

  8. python 装饰器 第八步:使用类来作为装饰器参数

    #第八步:使用类作为装饰器参数 #装饰器使用的操作类 class Wish: #祈求方法 def before(): print('饭前洗洗手') #还愿方法 def after(): print(' ...

  9. 爬虫(一)—— 请求库(一)requests请求库

    目录 requests请求库 爬虫:爬取.解析.存储 一.请求 二.响应 三.简单爬虫 四.requests高级用法 五.session方法(建议使用) 六.selenium模块 requests请求 ...

  10. 关于Ext4 extraParams 不能传递动态参数的问题解决办法

    可以监听请求发送之前的事件:beforeload ,然后再添加请求的参数 me.store = Ext.create('Ext.data.JsonStore', { remoteSort: true, ...