思想- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
模拟
枚举出所有的可能性: 到当前状态的方案数+=能到它的状态的方案数
(具体有哪几种情况下面有详解)
代码- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#define mod 1000000007 using namespace std; char c[1000010]; long long f[1000010][4][2],tmp;//0表示i为0,1表示i为1,2表示i为2,3表示i为*.0表示i-1不为*,1表示i-1为* int main(){ scanf("%s",c+1);//c第一位为 1 int l=strlen(c+1); if(c[1]=='1'||c[1]=='?') f[1][1][0]=1;//初定义:无论它们第一位是什么,前一位都没得选,便定为'*' if(c[1]=='2'||c[1]=='?');//第一位不可能为 2,因为它不可能两边都是'*' if(c[1]=='0'||c[1]=='?') f[1][0][0]=1; if(c[1]=='*'||c[1]=='?') f[1][3][0]=1; for(int i=2;i<=l;i++){ if(c[i]=='1'||c[i]=='?'){ f[i][1][0]=(f[i][1][0]+f[i-1][1][1]+f[i-1][0][0])%mod;//到达这种状态的几种方法 f[i][1][1]=(f[i][1][1]+f[i-1][3][0]+f[i-1][3][1])%mod; } if(c[i]=='2'||c[i]=='?'){ f[i][2][1]=(f[i][2][1]+f[i-1][3][0]+f[i-1][3][1])%mod; } if(c[i]=='0'||c[i]=='?'){ f[i][0][0]=(f[i][0][0]+f[i-1][1][1]+f[i-1][0][0])%mod; } if(c[i]=='*'||c[i]=='?'){ f[i][3][0]=(f[i][3][0]+f[i-1][1][0]+f[i-1][2][1])%mod; f[i][3][1]=(f[i][3][1]+f[i-1][3][0]+f[i-1][3][1])%mod; } } //注:因为不存在这两种情况:···2 或 ···f 1(f表示一个不是'*'的数)所以最后不用加这两种情况 tmp=(f[l][3][0]+f[l][3][1]+f[l][1][1]+f[l][0][0])%mod; printf("%lld",tmp); }
代码详解- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
f[ i ][ j ][ k ]: i 表示当前是第几个字符;j 表示这个字符是什么:' 0、1、2、* ' -> 0、1、2 、3('?'是什么都无所谓);k 表示前一位字符是否为 ' * '(0:Χ 1:√)
有以下几种情况(f为0、1、2中的一个):
1.当 c[i]=0或? 时:
······0 0 0····· 或······* 1 0 ->f[i][0][0]+=f[i-1][0][0]+f[i-1][1][1]
2.当 c[i]=1或? 时:
- c[i-1]=='*': ······f * 1······ 或 ······* * 1······ ->f[i][1][1]+=f[i-1][3][0]+f[i-1][3][1]
- c[i-1]!='*': ······f 0 1······ 或 ······* 1 1······ ->f[i][1][0]+=f[i-1][0][0]+f[i-1][1][1]
3.当 c[i]=2或?时:
······f * 2······ 或 ······* * 2······ ->f[i][2][1]+=f[i-1][3][0]+f[i-1][3][1]
4.当 c[i]='*'或?时:
- c[i-1]=='*': ······1 * *······ 或 ······* * *······ ->f[i][3][1]+=f[i-1][3][1]+f[i-1][3][1]
- c[i-1]!='*': ······f 1 *······ 或 ······* 2 *······ ->f[i][3][0]+=f[i-1][1][0]+f[i-1][2][1]
最后:因为不存在这两种情况:······2 或 ······f 1,所以
tmp=f[l][3][0]+f[l][3][1]+f[l][1][1]+f[l][0][0]