CF296B Yaroslav and Two Strings
link
题意
给定两个由数字和 ?
组成的字符串 \(s,t\),将 ?
替换为数字。若 \(s',t'\) 中有 \(s'_i>w'_i,s'_j<w'_j(1\leq i,j\leq n)\),则是一种合法的替换。求合法的方案数对 \(10^9+7\) 取模。\(1\leq n\leq 10^5\)。
题解
考虑 dp。设 \(f_{i,0/1,0/1}\) 表示第 \(i\) 位前有无 \(s_i>w_i\) 有无 \(s_i<w_i\)。转移直接枚举 \(s_i,w_i\) 的情况,\(f_{i,j|[c1>c2],k|[c1<c2]}=f_{i,j|[c1>c2],k|[c1<c2]}+f_{i-1,j,k}\)。注意初始 \(f_{0,0,0}=1\)。复杂度为大常数 \(O(n)\)。aclink。
坑
- 代码好写。
代码
#include<bits/stdc++.h>
#define i64 long long
#define L(a,b,c,d) for(int a=b;a<=c;a+=d)
#define R(a,b,c,d) for(int a=b;a>=c;a-=d)using namespace std;
const int N=1e5+5,M=1e9+7;void solve();
int n;
i64 f[N][2][2];
char s[N],t[N];signed main(){int Test=1;
// scanf("%d",&Test);while(Test--) solve();return 0;
}void solve(){scanf("%d",&n);scanf("%s%s",s+1,t+1);f[0][0][0]=1;L(i,1,n,1){L(x,0,1,1){L(y,0,1,1){L(j,0,9,1){L(k,0,9,1){if((s[i]=='0'+j||s[i]=='?')&&(t[i]=='0'+k||t[i]=='?')){f[i][x|(j>k)][y|(j<k)]=(f[i][x|(j>k)][y|(j<k)]+f[i-1][x][y])%M;}}}}}}printf("%lld\n",f[n][1][1]);
}