题意:有n个格子排成一列
对于一个格子,里面会有以下几种字符:
0:这个格子没有烈焰,且其左右两个格子均没有烈焰
1:这个格子没有烈焰,且其左右两个格子中只有一个烈焰
2:这个格子没有烈焰,且其左右两个格子中均有烈焰
*:这个格子有烈焰
?:未告诉你本格情况
求n个格子分布合理的情况数?
思路:dp
dp[i][0/1][0/1]表示前i位,当前位和下一位是(1)不是(0)烈焰的情况数
当s[i]='*'时, 该位是1:
dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])
dp[i][1][1]=(dp[i-1][0][1]+dp[i-1][1][1])
当s[i]='0'时,上一位、当前位和下一位都得是0:
dp[i][0][0]=dp[i-1][0][0]
当s[i]='1'时,上一位或下一位有一个是1:
dp[i][0][1]=dp[i-1][0][0]
dp[i][0][0]=dp[i-1][1][0]
当s[i]='2'时,上一位和下一位都是1,当前位为0:
dp[i][0][1]=dp[i-1][1][0];
当s[i]='?'时,上一位、当前位和下一位都随意:
dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])
dp[i][1][1]=(dp[i-1][0][1]+dp[i-1][1][1])
dp[i][0][0]=(dp[i-1][0][0]+dp[i-1][1][0])
dp[i][0][1]=(dp[i-1][0][0]+dp[i-1][1][0])
初值为dp[0][0][0] =1,dp[0][0][1] = 1
代码:
#include<bits/stdc++.h> #define inf 1000000007 using namespace std; typedef long long ll; ll dp[1000005][3][3]; int a[1000005]; int main() { char s[1000005]; int n; scanf("%s",(s+1)); n=strlen(s+1); dp[0][0][1]=1; dp[0][0][0]=1; for(int i=1;i<=n;i++) { if(s[i]=='*') { dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])%inf; dp[i][1][1]=(dp[i-1][0][1]+dp[i-1][1][1])%inf; } else if(s[i]=='0') { dp[i][0][0]=dp[i-1][0][0]; } else if(s[i]=='1') { dp[i][0][1]=dp[i-1][0][0]; dp[i][0][0]=dp[i-1][1][0]; } else if(s[i]=='2') { dp[i][0][1]=dp[i-1][1][0]; } else { dp[i][0][1]=(dp[i-1][1][0]+dp[i-1][0][0])%inf; dp[i][1][1]=(dp[i-1][1][1]+dp[i-1][0][1])%inf; dp[i][0][0]=(dp[i-1][1][0]+dp[i-1][0][0])%inf; dp[i][1][0]=(dp[i-1][1][1]+dp[i-1][0][1])%inf; } } ll z; if(s[n]=='?') { z=(dp[n][1][0]+dp[n][0][0])%inf; } else if(s[n]=='1'||s[n]=='0'||s[n]=='2') { z=(dp[n][0][0])%inf; } else { z=(dp[n][1][0])%inf; } cout << z <<endl; return 0; }