分析
考虑到整个序列只要有一对不合法的就可以贡献答案,我们可以设计以下几种方案来进行dp
设f[i][j]表示当前位置为 i ,状态为 j 的方案数:
j = 0 表示前面已经出现不合法的情况
j = 1 表示前面都是s小于等于w
j = 2 表示前面都是s大于等于w
j = 3 表示前面都是s等于w
具体转移详见代码
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const int maxn=1e5+5;
ll f[maxn][4];
int n;
char s[maxn],w[maxn];
int main()
{
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
scanf("%d",&n);
scanf("%s%s",s+1,w+1);
f[0][1]=f[0][2]=f[0][3]=1;
for(int i=1;i<=n;i++)
{
if(s[i]!='?' && w[i]!='?')
{
f[i][0]=((f[i-1][0]+f[i-1][1]*(s[i]>w[i])+f[i-1][2]*(s[i]<w[i])-f[i-1][3]*(s[i]!=w[i]))%mod+mod)%mod;
if(s[i]<=w[i]) f[i][1]=f[i-1][1];
if(s[i]>=w[i]) f[i][2]=f[i-1][2];
if(s[i]==w[i]) f[i][3]=f[i-1][3];
}
if(s[i]=='?' && w[i]!='?')
{
f[i][0]=((10*f[i-1][0]+(9-(w[i]-'0'))*f[i-1][1]+(w[i]-'0')*f[i-1][2]-f[i-1][3]*9)%mod+mod)%mod;
f[i][1]=((w[i]-'0')+1)*f[i-1][1]%mod;
f[i][2]=(10-(w[i]-'0'))*f[i-1][2]%mod;
f[i][3]=f[i-1][3]%mod;
}
if(s[i]!='?' && w[i]=='?')
{
f[i][0]=(10*f[i-1][0]%mod+(s[i]-'0')*f[i-1][1]%mod+(9-(s[i]-'0'))*f[i-1][2]%mod-9*f[i-1][3]%mod+mod)%mod;
f[i][1]=(10-(s[i]-'0'))*f[i-1][1]%mod;
f[i][2]=((s[i]-'0')+1)*f[i-1][2]%mod;
f[i][3]=f[i-1][3]%mod;
}
if(s[i]=='?' && w[i]=='?')
{
f[i][0]=(100*f[i-1][0]%mod+45*f[i-1][1]%mod+45*f[i-1][2]%mod-90*f[i-1][3]%mod+mod)%mod;
f[i][1]=55*f[i-1][1]%mod;
f[i][2]=55*f[i-1][2]%mod;
f[i][3]=10*f[i-1][3]%mod;
}
}
printf("%lld\n",f[n][0]%mod);
return 0;
}