1. 程式人生 > 其它 >Codeforces296 B. Yaroslav and Two Strings(dp)

Codeforces296 B. Yaroslav and Two Strings(dp)

題意:

在這裡插入圖片描述
答案對1e9+7取模。

資料範圍:n<=1e5

解法:

令d[i][j][k]表示前i個字元,是否存在si<wi,是否存在sj>wj,的方案數.
遇到問號的時候,對問號位置的數從09列舉,根據狀態變化進行dp轉移就行了.

code:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=2e6+5;
const int mod=1e9+7;
int d[maxm][2][2];
char s[maxm];
char t[maxm];
int n;
signed main(){ ios::sync_with_stdio(0);cin.tie(0); cin>>n; cin>>(s+1); cin>>(t+1); d[0][0][0]=1; for(int i=0;i<n;i++){ for(int j=0;j<2;j++){ for(int k=0;k<2;k++){//列舉當前狀態 if(!d[i][j][k])continue; char mi1,ma1;
char mi2,ma2; if(s[i+1]=='?')mi1='0',ma1='9'; else mi1=ma1=s[i+1]; if(t[i+1]=='?')mi2='0',ma2='9'; else mi2=ma2=t[i+1]; for(char x=mi1;x<=ma1;x++){ for(char y=mi2;y<=ma2;y++){//列舉下一個狀態
if(x<y){ d[i+1][1][k]+=d[i][j][k]; d[i+1][1][j]%=mod; }else if(x>y){ d[i+1][j][1]+=d[i][j][k]; d[i+1][j][1]%=mod; }else if(x==y){ d[i+1][j][k]+=d[i][j][k]; d[i+1][j][k]%=mod; } } } } } } int ans=d[n][1][1]; cout<<ans<<endl; return 0; }