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. CSS中的flex布局

    1.flex 布局的概念 Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性.任何一个容器都可以指定为 Flex 布局,行内元素也可以通过 ...

  2. Flutter 中的基本路由

    Flutter 中的路由通俗的讲就是页面跳转.在 Flutter 中通过 Navigator 组件管理路由导航,并提供了管理堆栈的方法.如:Navigator.push 和 Navigator.pop ...

  3. h5视频做背景的样式

    video{ position: fixed; display: block; width: 100%; object-fit:fill; height:100%; right: 0px; botto ...

  4. SpringBoot 快速构建微服务体系 知识点总结

    可以通过http://start.spring.io/构建一个SpringBoot的脚手架项目 一.微服务 1.SpringBoot是一个可使用Java构建微服务的微框架. 2.微服务就是要倡导大家尽 ...

  5. hdu 5564 Clarke and digits

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5564 ------------------------------------------------ ...

  6. leetcode-解题记录 557. 反转字符串中的单词 III

    题目: 给定一个字符串,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序. 示例 1: 输入: "Let's take LeetCode contest" 输出 ...

  7. 开源 NAS 操作系统不完全汇总

    市面上能见到的 NAS 操作系统很多,有如 FreeNAS 这样意气风发的开源免费版,也有完全商业的闭源版本,更有如黑群晖之类的破解版本.NAS 系统的迭代是一个大浪淘沙的过程,活下来的系统在功能上逐 ...

  8. 用Linux 搭建 PXE 网络引导环境

    本例子中使用了CentOS7.4 minimal 系统,并且关闭了防火墙和selinux,并使用了dhcp.tftp.http和samba服务. 假设PXE服务器是192.168.4.104 ,tft ...

  9. js实现的页面加载完毕之前loading提示效果

    页面加载readyState的五种状态 原文如下: 0: (Uninitialized) the send( ) method has not yet been invoked. 1: (Loadin ...

  10. 实验报告(七)&第九周课程总结

    班级 计科二班 学号 20188425 姓名 IM 完成时间2019/10/24 评分等级 实验任务详情: 完成火车站售票程序的模拟. 要求: (1)总票数1000张: (2)10个窗口同时开始卖票: ...