应该很容易看出是要用dp解决的,然后我开了个二维的dp[i][0/1]表示i号位置有没有火焰,结果好像发现情况分不太清楚。

题目大意:
直接看题目吧。

思路:
如果设置为dp[i][0/1]表示i号位置有无火焰的话,当前是1的时候,我们需要判断i+1位和i-1位的情况。但是由于dp从小到大,所以我无法判断i+1的情况了,于是我就做不下去了。
后来看了题解,发现有人用这个二维dp做的。居然直接去判断后面i+1位的情况。。。
居然还可以这样,哎,对dp的理解太浅了。

看了大部分的题解是,dp[i][0/1][0/1]表示第i个位置有无火焰并且第i+1个位置有无火焰的方案。
这样子的话,从上一个位置转移过来的时候,我们转移状态其实就可以搞清楚了。
具体见代码。这里初始化要让dp[0][0][0]=dp[0][0][1]=1

代码:

#include<bits/stdc++.h>
using namespace std;
char s[1000040];
const long long mod=1000000007;
long long f[1000400][2][2];
int main()
{
    cin>>s+1;
    int n=strlen(s+1);
    //cout<<n<<endl<<s+1<<endl;
    f[0][0][0]=1;f[0][0][1]=1;
    for(int i=1;i<=n;i++){
        if(s[i]=='*'){
            f[i][1][0]=(f[i-1][1][1]+f[i-1][0][1])%mod;
            f[i][1][1]=(f[i-1][1][1]+f[i-1][0][1])%mod;
        }
        if(s[i]=='0'){
            f[i][0][0]=f[i-1][0][0];
        }
        if(s[i]=='1'){
            f[i][0][0]=f[i-1][1][0];
            f[i][0][1]=f[i-1][0][0];
        }
        if(s[i]=='2'){
            f[i][0][1]=f[i-1][1][0];
        }
        if(s[i]=='?'){
            f[i][0][1]=(f[i-1][1][0]+f[i-1][0][0])%mod;
            f[i][0][0]=(f[i-1][1][0]+f[i-1][0][0])%mod;
            f[i][1][1]=(f[i-1][0][1]+f[i-1][1][1])%mod;
            f[i][1][0]=(f[i-1][0][1]+f[i-1][1][1])%mod;
        }
    }
    cout<<(f[n][0][0]+f[n][1][0])%mod<<endl;
    return 0;
}