字符串dp——牛客多校第五场G
比赛的时候脑瘫了没想出来。。打多校以来最自闭的一场
显然从s中选择大于m个数组成的数必然比t大,所以只要dp求出从s中选择m个数大于t的方案数
官方题解是反着往前推,想了下反着推的确简单,因为高位的数优先级高,如果高位满足条件,那么低位只要用组合数求一下就行
#include<bits/stdc++.h>
using namespace std;
#define maxn 3005
#define ll long long
#define mod 998244353
int n,m;
char s[maxn],t[maxn];
ll dp[maxn][maxn];//dp[i][j]表示后面i个字符中取j个,比t大的方案数
ll C[maxn][maxn];
void init(){
C[][]=;
for(int i=;i<=;i++){
C[i][]=;
for(int j=;j<=i;j++)
C[i][j]=(C[i-][j]+C[i-][j-])%mod;
}
} void reserve(char s[]){
int len=strlen(s);
int i=,j=len-;
while(i<j){
swap(s[i],s[j]);
++i,--j;
}
}
int main(){
int T;cin>>T;
init();
while(T--){
cin>>n>>m;
scanf("%s",s+);
scanf("%s",t+);
if(m>n){puts("");continue;} for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
dp[i][j]=; reserve(s+);
reserve(t+);
for(int i=;i<=n;i++){
//dp[i][0]=1;
for(int j=;j<=m&&j<=i;j++){
dp[i][j]=dp[i-][j];//不选第i位
if(s[i]>t[j])
dp[i][j]=(dp[i][j]+C[i-][j-])%mod;
if(s[i]==t[j])
dp[i][j]=(dp[i][j]+dp[i-][j-])%mod;
}
} ll ans=dp[n][m]; reserve(s+);
for(int i=;i<=n;i++)if(s[i]!=''){
for(int j=m;j<=n-i;j++)
ans=(ans+C[n-i][j])%mod;
}
cout<<ans<<'\n';
}
}
然后是正着往后推,其实难度也不大,只不过状态表示为dp[i][j]为s中前i个取j个,和t取前j个相等的情况,然后转移过程中更新ans即可
#include <bits/stdc++.h>
using namespace std; typedef long long LL; const int MAXN=,MOD=; int C[MAXN][MAXN],dp[MAXN][MAXN];
char a[MAXN],b[MAXN]; void solve()
{
int n,m;
scanf("%d%d%s%s",&n,&m,a+,b+);
int ans=;
for (int i=;i<=n;i++)
if (a[i]!='')
for (int j=m;j<=n-i;j++)
(ans+=C[n-i][j])%=MOD;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
dp[i][j]=;
dp[][]=;
for (int i=;i<=n;i++)
{
dp[i][]=;
for (int j=;j<=m;j++)
{
dp[i][j]=dp[i-][j];
if (a[i]==b[j])
(dp[i][j]+=dp[i-][j-])%=MOD;
else if (a[i]>b[j])
ans=(ans+(LL)dp[i-][j-]*C[n-i][m-j])%MOD;
}
}
printf("%d\n",ans);
} int main()
{
#ifdef local
freopen("read.txt","r",stdin);
#endif
for (int i=;i<=;i++)
{
C[i][]=;
for (int j=;j<=i;j++)
C[i][j]=(C[i-][j-]+C[i-][j])%MOD;
}
int T;
scanf("%d",&T);
while (T--) solve();
return ;
}
字符串dp——牛客多校第五场G的更多相关文章
- 2019牛客多校第五场 G subsequence 1 dp+组合数学
subsequence 1 题意 给出两个数字串s,t,求s的子序列中在数值上大于t串的数量 分析 数字大于另一个数字,要么位数多,要么位数相同,字典序大,位数多可以很方便地用组合数学来解决,所以只剩 ...
- 牛客多校第五场G
subsequence 1 只要处理长度等于t的. 转移方程没想出来QAQ $dp(i,j,0)$代表到$s[i]$为止有多少个前缀序列与$t[0\cdots j]$相同 所以有$dp(i,j,0)= ...
- 牛客多校第五场 G subsequence 1 最长公共子序列/组合数
题意: 给定两个由数字组成的序列s,t,找出s所有数值大于t的子序列.注意不是字典序大. 题解: 首先特判s比t短或一样长的情况. 当s比t长时,直接用组合数计算s不以0开头的,长度大于t的所有子序列 ...
- 牛客多校第三场 G Removing Stones(分治+线段树)
牛客多校第三场 G Removing Stones(分治+线段树) 题意: 给你n个数,问你有多少个长度不小于2的连续子序列,使得其中最大元素不大于所有元素和的一半 题解: 分治+线段树 线段树维护最 ...
- 牛客多校第五场 F take
链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 题目描述 Kanade has n boxes , the i-th box has p[i] ...
- 牛客多校第五场 J:Plan
链接:https://www.nowcoder.com/acm/contest/143/J 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...
- 牛客多校第五场-D-inv
链接:https://www.nowcoder.com/acm/contest/143/D来源:牛客网 题目描述 Kanade has an even number n and a permutati ...
- 牛客多校第五场 F take 期望转化成单独事件概率(模板) 树状数组
链接:https://www.nowcoder.com/acm/contest/143/F来源:牛客网 Kanade has n boxes , the i-th box has p[i] proba ...
- 牛客多校第五场 E room 二分图匹配 KM算法模板
链接:https://www.nowcoder.com/acm/contest/143/E来源:牛客网 Nowcoder University has 4n students and n dormit ...
随机推荐
- 基于React Native的跨三端应用架构实践
作者|陈子涵 编辑|覃云 “一次编写, 到处运行”(Write once, run anywhere ) 是很多前端团队孜孜以求的目标.实现这个目标,不但能以最快的速度,将应用推广到各个渠道,而且还能 ...
- vue 项目 跳转 页面 不刷新 问题
vue项目中需要导出下载客户数据,因为数据太多,响应太慢.后台直接上传给七牛 然后返回一个下载链接 前端通过跳转链接 来下载 riskManagementApi.friendExprotAll(t ...
- ac自动机暴力跳fail匹配——hdu5880
很简单的题,ac自动机里再维护一个len表示每个状态的串长,用s去query时每到一个结点都要暴力跳fail,因为有可能这个结点不是,但是其fail是危险结点,找到一个就直接break 再用个差分数组 ...
- python实现收邮件判断模块poplib,email
一.代码 # 输入邮件地址, 口令和POP3服务器地址: import datetime import email import poplib import email.policy from ema ...
- (转)openfire插件开发(三)通过http方式向openfire客户端发信息
转:http://blog.csdn.net/hzaccp3/article/details/19964655 需求: 通过http方式,向openfire客户端发信息(非XMPP协议)openfi ...
- linux基础知识汇总(四)--ps grep命令
转:http://www.cnblogs.com/allen8807/archive/2010/11/10/1873843.html http://www.cnblogs.com/end/archiv ...
- java程序中线程cpu使用率计算
原文地址:https://www.imooc.com/article/27374 最近确实遇到题目上的刚需,也是花了一段时间来思考这个问题. cpu使用率如何计算 计算使用率在上学那会就经常算,不过往 ...
- 1.6 USB的插入检测机制
- Junit用断言对控制台输出进行测试
核心思路: 在测试前,将标准输出定向到ByteArrayOutputStream中去 用输出流文件断言内容 测试完成,将标准输出修改为console 具体操作示例 基本通用复制粘贴操作 public ...
- 错误 1 error C4996: 'getcwd': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _getcwd. See online help for details.
解决办法: 属性>C/C++>预处理定义>编辑>添加_CRT_NONSTDC_NO_DEPRECATE>应用