CodeForces

来源:互联网 发布:串口读取电子秤数据 编辑:程序博客网 时间:2024/06/06 03:05

CF404D传送门

 题意:一维版本的扫雷游戏,给出一些状态,用其它的去填充,问有多少种?


 分析:每一个位置填充什么与它前一个和后一个状态有关,形成啦递推关系。由此可以用DP求解。

 设 dp[i][0] 表示第i个位置有雷

dp[i][1]表示第i个位置无雷,左边有雷 右边无雷

dp[i][2]表示第i个位置无雷,左边无雷 右边有雷

dp[i][3]表示第i个位置无雷,左边有雷 右边有雷

dp[i][4]表示第i个位置无雷,左边无雷 右边无雷

状态确定啦状态转移方程就很容易得出啦。


#include<cstring>#include<iostream>#include<cstdio>#include<algorithm>using namespace std;const int MOD=1e9+7;char s[1000100];int n,dp[1000100][5];int main(){    while(scanf(" %s",s+1)!=EOF)    {        memset(dp,0,sizeof(dp));        n=strlen(s+1);         dp[0][2]=1;        dp[0][4]=1;        for(int i=1;i<=n;i++)        {            if(s[i]=='?')            {                dp[i][0]=((dp[i-1][0]+dp[i-1][2])%MOD+dp[i-1][3])%MOD;                dp[i][1]=dp[i-1][0];                dp[i][2]=(dp[i-1][4]+dp[i-1][1])%MOD;                dp[i][3]=dp[i-1][0];                dp[i][4]=(dp[i-1][1]+dp[i-1][4])%MOD;            }            else if(s[i]=='0')            {                dp[i][4]=(dp[i-1][1]+dp[i-1][4])%MOD;            }            else if(s[i]=='*')            {                 dp[i][0]=((dp[i-1][0]+dp[i-1][2])%MOD+dp[i-1][3])%MOD;            }            else if(s[i]=='1')            {                dp[i][1]=dp[i-1][0];                dp[i][2]=(dp[i-1][4]+dp[i-1][1])%MOD;            }            else if(s[i]=='2')            {                 dp[i][3]=dp[i-1][0];            }        }        int ans=0;            ans=((dp[n][1]+dp[n][0])%MOD+dp[n][4])%MOD;        printf("%d\n",ans);    }    return 0;}