比赛的时候脑瘫了没想出来。。打多校以来最自闭的一场

显然从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 ;
}

最新文章

  1. bzoj3095--数学题
  2. 设计模式学习笔记c++版——单例模式
  3. LightOJ 1245 数学题,找规律
  4. private成员变量真的私有吗?(用指针刨他祖坟)
  5. TCP/IP协议原理与应用笔记20:直接交付 和 间接交付
  6. HDU 4293 Groups (线性dp)
  7. codevs 1743 反转卡片
  8. 李洪强漫谈iOS开发[C语言-020]-scanf的本质
  9. VB6.0连接MySQL数据库
  10. cas单点登录系统:客户端(client)详细配置
  11. 如何在.xml中配置Servlet信息
  12. WinForm加载外部类库项目的集成开发模式
  13. slice 与 splice 的区别
  14. 从零开始学 Web 之 Vue.js(六)Vue的组件
  15. 63.(原65)纯 CSS 创作一个摇摇晃晃的 loader
  16. javascript 浮点数比较
  17. 深入理解Connector
  18. poj1961 &amp; hdu1358 Period【KMP】
  19. timer Compliant Controller project (3)--bom and sch
  20. 01 awk工具的使用

热门文章

  1. Makefile中的$(addprefix),添加前缀,指定目标生成目录
  2. 【BZOJ5093】图的价值
  3. CF734E Anton and Tree
  4. js关闭当前窗口的几种方法
  5. delphi 设备函数GetDeviceCaps函数
  6. 存储emoji表情,修改字符集为utf8mb4
  7. SCP-bzoj-1054
  8. position:fixed 造成页面抖动解决办法
  9. [bzoj3033]太鼓达人 题解(搜索)
  10. [ZJOI2010]排列计数 题解