2019牛客多校第五场G-subsequence 1 DP
G-subsequence 1
题意
给你两个字符串\(s、t\),问\(s\)中有多少个子序列能大于\(t\)。
思路
令\(len1\)为\(s\)的子序列的长度,\(lent\)为\(t\)的长度
- \(len1 > lent\):枚举每一位,如果当前为不为\(0\)那么它后面的位置可以随意取,\(num = num + \binom{k}{len-1}、k\)是当前位到\(s\)的末尾剩下的位数
- \(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\)
- 用一个前缀和维护一下\(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的更多相关文章
- 2019牛客多校第五场 G subsequence 1 dp+组合数学
subsequence 1 题意 给出两个数字串s,t,求s的子序列中在数值上大于t串的数量 分析 数字大于另一个数字,要么位数多,要么位数相同,字典序大,位数多可以很方便地用组合数学来解决,所以只剩 ...
- 2019牛客多校第五场H - subsequence 2 拓扑
H - subsequence 2 题意 要你使用前\(m\)个小写字母构造一个长度为\(n\)的字符串 有\(m*(m-1)/2\)个限制条件: \(c_{1} .c_{2}. len\):表示除去 ...
- 牛客多校第五场 G subsequence 1 最长公共子序列/组合数
题意: 给定两个由数字组成的序列s,t,找出s所有数值大于t的子序列.注意不是字典序大. 题解: 首先特判s比t短或一样长的情况. 当s比t长时,直接用组合数计算s不以0开头的,长度大于t的所有子序列 ...
- 2019牛客多校第五场 generator 1——广义斐波那契循环节&&矩阵快速幂
理论部分 二次剩余 在数论中,整数 $X$ 对整数 $p$ 的二次剩余是指 $X^2$ 除以 $p$ 的余数. 当存在某个 $X$,使得式子 $X^2 \equiv d(mod \ p)$ 成立时,称 ...
- 2019牛客多校第五场generator2——BSGS&&手写Hash
题目 几乎原题 BZOJ3122题解 分析 先推一波公式,然后除去特殊情况分类讨论,剩下就是形如 $a^i \equiv b(mod \ p)$ 的方程,可以使用BSGS算法. 在标准的BSGS中,内 ...
- 2019牛客多校第五场F maximum clique 1 最大独立集
题意:给你n个数,现在让你选择一个数目最大的集合,使得集合中任意两个数的二进制表示至少有两位不同,问这个集合最大是多大?并且输出具体方案.保证n个数互不相同. 思路:容易发现,如果两个数不能同时在集合 ...
- 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}\) 思路 一般看 ...
- 2019牛客多校第五场B-generator 1(矩阵快速幂)
generator 1 题目传送门 解题思路 矩阵快速幂.只是平时的矩阵快速幂是二进制的,这题要用十进制的快速幂. 代码如下 #include <bits/stdc++.h> #defin ...
- 2019 牛客多校第五场 B generator 1
题目链接:https://ac.nowcoder.com/acm/contest/885/B 题目大意 略. 分析 十进制矩阵快速幂. 代码如下 #include <bits/stdc++.h& ...
随机推荐
- 如何稀释 流事件 (如,onscroll、change、input、mouseover 等 事件)
1.问题引入:https://segmentfault.com/q/1010000000707337?_ea=62905 2.javascript中的函数节流和函数去抖:https://www.cnb ...
- window安装nodejs
nvm管理nodejs 原文: https://www.cnblogs.com/shimily/articles/7244058.html1.下载nvm(nodejs版本管理工具) https://g ...
- linux6.5 RPM方式安装 mysql5.6
步骤一.检查下linux是不是已经安装了MySQL # rpm -qa|grep mysql mysql-libs-5.1.71-1.el6.x86_64 # rpm -e --nodeps mysq ...
- python类与对象练习题扑克牌
#定义一个扑克类,属性是颜色,数字.#定义一个手类,属性是扑克牌得颜色数字#定义一个人类,属性是左手,右手.类里定义一些方法,比如交换,展示 class Poker : def __init__(se ...
- java并发编程笔记(十一)——高并发处理思路和手段
java并发编程笔记(十一)--高并发处理思路和手段 扩容 垂直扩容(纵向扩展):提高系统部件能力 水平扩容(横向扩容):增加更多系统成员来实现 缓存 缓存特征 命中率:命中数/(命中数+没有命中数) ...
- Shiro那些事儿(一): Shiro初探
引言 权限,可以简单的理解成你能干什么,不能干什么.在管理系统中,对权限的设计可以很简单,也可以很复杂.简单点的,基本都是基于角色扮演的方式,比如系统管理员角色可以操作哪些菜单,普通用户角色可以操作哪 ...
- Prim算法生成迷宫
初始化地图 function initMaze(r,c){ let row = new Array(2 * r + 1) for(let i = 0; i < row.length; i++){ ...
- scrapy爬虫值Items
Items有哪些知识? 1.声明 import scrapy class Product(scrapy.Item): name = scrapy.Field() price = scrapy.Fiel ...
- 微信小程序实战篇-分类页面制作
https://blog.csdn.net/u012927188/article/details/73650264
- 大众点评Java开发实时应用监控平台-CAT
CAT介绍 CAT是基于Java开发的实时应用监控平台,包括实时应用监控,业务监控. CAT作为大众点评网基础监控组件,它已经在中间件框架(MVC框架,RPC框架,数据库框架,缓存框架等)中得到广泛应 ...