这道题还是比较容易能看得出是dp的。但是这个状态设计我不会,参考了大佬们的题解。
这个状态的设计需要考虑到:由于每个格子的状态和前后都有关,所以,单纯一个维度是不足以准确表示状态然后进行状态转移的。俗话说得好:表达不准确?再来一维(我自己编的23333),我们可以考虑多维表示状态。
因为想到:我们要确定一个格子的状态,我们还需要的就是前一个格子的信息,因此,前一个格子需要记录自己的信息。另外,这个格子的信息还和后一个格子有关,所以,还需要一个维度表示后对后一个一个格子的要求.自然的,格子本身的位置需要记录下,因此,我们考虑开这样一个三维数组,定义状态:
dp[i][j][k]:
i表示位置。
若j==1,则自己带火,若j==0,则自身没火
若k==1,则下一格带火,否则,下一格不带火
然后,根据题目要求进行状态转移就行了。
另外,还要注意下初始条件的设置,这点也比较麻烦。
最重要的,记得mod

#include <iostream>
#include <map>
#include <ctime>
#include <vector>
#include <climits>
#include <algorithm>
#include <random>
#include <cstring>
#include <cstdio>
#include <map>
#include <set>
#include <bitset> 
#include <queue>
#define inf 0x3f3f3f3f
#define IOS ios_base::sync_with_stdio(0); cin.tie(0);
#define rep(i, a, n) for(register int i = a; i <= n; ++ i)
#define per(i, a, n) for(register int i = n; i >= a; -- i)
#define ONLINE_JUDGE
using namespace std;
typedef long long ll;
const int mod=1e9+7;
template<typename T>void write(T x)
{
    if(x<0)
    {
        putchar('-');
        x=-x;
    }
    if(x>9)
    {
        write(x/10);
    }
    putchar(x%10+'0');
}

template<typename T> void read(T &x)
{
    x = 0;char ch = getchar();ll f = 1;
    while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();}
    while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f;
}
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;};
ll ksm(ll a,ll n){//看是否要mod 
    ll ans=1;
    while(n){
        if(n&1) ans=(ans*a)%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans%mod;
}
//==============================================================
const int maxn=1e6+10;
int dp[maxn][2][2]={0};
char str[maxn];

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    freopen("out.txt","w",stdout);
    #endif
    clock_t c1 = clock();
    //===========================================================
    scanf("%s",str+1);
    int len=strlen(str+1);
    if(str[1]=='*'){
        dp[0][0][1]=1;
    }
    else if(str[1]=='?'){
        dp[0][0][1]=1;
        dp[0][0][0]=1;
    }
    else{
        dp[0][0][0]=1;
    }
    rep(i,1,len){

        if(str[i]=='0'){
            dp[i][0][0]=(dp[i-1][0][0])%mod;
        }
        if(str[i]=='1'){
            dp[i][0][1]=(dp[i-1][0][0])%mod;
            dp[i][0][0]=(dp[i-1][1][0])%mod;
        }
        if(str[i]=='2'){
            dp[i][0][1]=(dp[i-1][1][0])%mod;
        }
        if(str[i]=='*'){
            dp[i][1][1]=(dp[i][1][0]=dp[i-1][1][1]+dp[i-1][0][1])%mod;
        }
        if(str[i]=='?'){
            dp[i][1][0]=dp[i][1][1]=(dp[i-1][1][1]+dp[i-1][0][1])%mod;
            dp[i][0][0]=dp[i][0][1]=(dp[i-1][0][0]+dp[i-1][1][0])%mod;
        }
    }
    write((dp[len][0][0]+dp[len][1][0])%mod);
    //===========================================================
    std::cerr << "Time:" << clock() - c1 << "ms" << std::endl;
    return 0;
}