题意:有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;
}

京公网安备 11010502036488号