D-Double Strings
fi,jf_{i,j}fi,j​表示a中前i个字符,b中前j个字符相同子序列的数量,容斥转移

fi,j=fi−1,j+fi,j−1−fi−1,j−1+{(1+fi−1,j−1)[ai=aj]}f_{i,j}=f_{i-1,j}+f_{i,j-1}-f_{i-1,j-1}+\{(1+f_{i-1,j-1})[a_i=a_j]\}fi,j​=fi−1,j​+fi,j−1​−fi−1,j−1​+{(1+fi−1,j−1​)[ai​=aj​]}

gi,jg_{i,j}gi,j​表示a中前i个字符,b中前j个字符满足小于关系子序列的数量

类似相同子序列数量转移即可。
gi,j=gi−1,j+gi,j−1−gi−1,j−1+(1+gi−1,j−1)+{(fi−1,j−1+1)[ai<aj]}g_{i,j}=g_{i-1,j}+g_{i,j-1}-g_{i-1,j-1}+(1+g_{i-1,j-1})+\{(f_{i-1,j-1}+1)[a_i<a_j]\}gi,j​=gi−1,j​+gi,j−1​−gi−1,j−1​+(1+gi−1,j−1​)+{(fi−1,j−1​+1)[ai​<aj​]}

Code1

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
const int N=5010;
const ll mod=1000000007;
char a[N],b[N];
int f[N][N],g[N][N];
int n,m;
int main()
{scanf("%s%s",a+1,b+1);n=strlen(a+1);m=strlen(b+1);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(a[i]==b[j])f[i][j]=(1ll*f[i-1][j]+f[i][j-1]+1)%mod;elsef[i][j]=(1ll*mod+f[i-1][j]+f[i][j-1]-f[i-1][j-1])%mod;}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(a[i]<b[j]) g[i][j]=(1ll*g[i-1][j]+g[i][j-1]+1+f[i-1][j-1])%mod;elseg[i][j]=(1ll*g[i-1][j]+g[i][j-1])%mod;}printf("%lld\n",g[n][m]);
}

Code2

首先求出相同子序列,然后枚举哪个位置不同,即第一个ai<aja_i<a_jai​<aj​,然后利用下面公式加快计算。

∑0≤i≤k(ni)(mk−i)=(n+mk)\sum_{0\leq i\leq k}\dbinom{n}{i}\dbinom{m}{k-i}=\dbinom{n+m}{k}0≤i≤k∑​(in​)(k−im​)=(kn+m​)

于是有
∑0≤i≤m(ni)(mi)∑0≤i≤m(ni)(mm−i)=(n+mm)\sum_{0\leq i\leq m}\dbinom{n}{i}\dbinom{m}{i}\sum_{0\leq i\leq m}\dbinom{n}{i}\dbinom{m}{m-i}=\dbinom{n+m}{m}0≤i≤m∑​(in​)(im​)0≤i≤m∑​(in​)(m−im​)=(mn+m​)

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
template <class T=int> T rd()
{T res=0;T fg=1;char ch=getchar();while(!isdigit(ch)) {if(ch=='-') fg=-1;ch=getchar();}while( isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();return res*fg;
}
const int N=5010;
const int mod=1000000007;
char a[N],b[N];
int f[N][N];
int n,m;
int fac[N<<1],inv[N<<1];
ll qmi(ll a,ll b){ll v=1;while(b){if(b&1) v=v*a%mod;a=a*a%mod;b>>=1;}return v;}
void init()
{fac[0]=1;for(int i=1;i<=10000;i++) fac[i]=1ll*fac[i-1]*i%mod;inv[10000]=qmi(fac[10000],mod-2);for(int i=9999;i>=0;i--) inv[i]=1ll*inv[i+1]*(i+1)%mod;
}
int C(int n,int m){return 1ll*fac[n]*inv[m]%mod*inv[n-m]%mod;}
int main()
{init();scanf("%s%s",a+1,b+1);n=strlen(a+1);m=strlen(b+1);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(a[i]==b[j])f[i][j]=(1ll*f[i-1][j]+f[i][j-1]+1)%mod;elsef[i][j]=(1ll*mod+f[i-1][j]+f[i][j-1]-f[i-1][j-1])%mod;}ll ans=0;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(a[i]<b[j])ans=(ans+1ll*(f[i-1][j-1]+1)*C(n-i+m-j,n-i)%mod)%mod;printf("%lld\n",ans);
}

2021牛客暑期多校训练营5 D-Double Strings(dp+组合数)相关推荐

  1. 【2021牛客暑期多校训练营5】Double Strings(二维字符串dp)

    D Double Strings 题意: 给出两个字符串A, B, 在其中选出两个等长的子序列(可以不连续)a, b,满足a的字典序严格小于b,求这样的方案有多少个,答案mod(1e9+7) 思路: ...

  2. 2021牛客暑期多校训练营3A-Guess and lies【dp】

    正题 题目链接:https://ac.nowcoder.com/acm/contest/11254/A 题目大意 现在有一个y∈[1,n]y\in[1,n]y∈[1,n],BobBobBob每次可以选 ...

  3. 2021牛客暑期多校训练营8 J-Tree(思维dp+rmq)

    J-Tree Cosmic_Tree题解 赛时队友想到了预处理s→ts\to ts→t路径上的点最远到达的点,后面贪心做的一直wa.正解是dp. 下面的solve(l,r,op)\text{solve ...

  4. 2021牛客暑期多校训练营9

    2021牛客暑期多校训练营9 题号 题目 知识点 A A Math Challenge B Best Subgraph C Cells D Divide-and-conquer on Tree E E ...

  5. 2021牛客暑期多校训练营5

    2021牛客暑期多校训练营5 题号 题目 知识点 A Away from College B Boxes 概率 C Cheating and Stealing D Double Strings 线性d ...

  6. 2021牛客暑期多校训练营4

    2021牛客暑期多校训练营4 题号 题目 知识点 A Course B Sample Game C LCS D Rebuild Tree E Tree Xor 思维+线段树 F Just a joke ...

  7. 2021牛客暑期多校训练营3

    2021牛客暑期多校训练营3 题号 题目 知识点 A Guess and lies B Black and white C Minimum grid 二分图匹配 D Count E Math 数论+打 ...

  8. 2021牛客暑期多校训练营2

    2021牛客暑期多校训练营2 题号 题目 知识点 A Arithmetic Progression B Cannon C Draw Grids D Er Ba Game E Gas Station F ...

  9. 2021牛客暑期多校训练营1

    2021牛客暑期多校训练营1 题号 题目 知识点 难度 A Alice and Bob 博弈论 B Ball Dropping 计算几何 签到 C Cut the Tree D Determine t ...

  10. 2021牛客暑期多校训练营2,签到题CDFKI

    2021牛客暑期多校训练营2 题号 标题 已通过代码 通过率 团队的状态 A Arithmetic Progression 点击查看 6/72 未通过 B Cannon 点击查看 34/104 未通过 ...

最新文章

  1. 高性能千万级定时任务管理服务forsun使用详解
  2. matlab mobile中文版,MATLAB Mobile
  3. Vue指令篇_v-model_数据双向绑定
  4. java socket编程实现聊天程序_java Socket编程 聊天程序 服务器端和客户端
  5. 优秀的开发者从命名开始
  6. 黑马微信小程序项目实战
  7. 你知道CDN是什么吗?本文带你搞明白CDN
  8. MSP430编程器仿真器JTAG、SBW、BSL接口的区别
  9. CS:APP Archlab(未完待续)
  10. Unity 将图片转换成 sprite 格式
  11. 卡塔尔世界杯出现了半自动越位识别技术、Feelix Palm、动作轨迹捕捉等黑科技,一起来看看吧。
  12. 智能客服工单系统与工单管理系统的区别
  13. C#子窗体控制父窗体dgv刷新
  14. java应届生如何找工作?
  15. 二次规划及qpoases简要介绍
  16. 一个TCP连接总是以1KB的最大段发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为16KB时发生了超时,如果接下来的4个RTT(往返时间)时间内的TCP段的传输都是成功的,那么当第4个RTT时间
  17. 【论文阅读】【综述】3D Object Detection 3D目标检测综述
  18. 工具nmap常用命令总结
  19. Android Studio出现Execution failed for task ‘:app:processDebugMainManifest
  20. 中国各朝代统治时间列表

热门文章

  1. xps13安装linux系统,[操作系统]Dell XPS 13 (9360)安装配置 ubuntu 16.04 实现 win10 Linux双系统...
  2. java thread join()_Java Thread join() 的用法
  3. lmbs PHP,PHP 清空 MySql 指定数据表中的所有数据
  4. linux c 数据库访问框架,linux c 开发通用结构,框架
  5. 量子计算机与新型传感器,新型量子传感器为超导量子计算机发展开辟了新路径...
  6. 算法与数据结构——并查集
  7. php防止cc攻击代码,防cc攻击PHP防CC攻击实现代码
  8. ajax option请求后无post请求_ThingJS:一种浏览器、服务器和技术的新组合方法——Ajax...
  9. [C++STL]常用查找算法
  10. [Java基础]哈希值