1. 程式人生 > >codeforce404 D. Minesweeper 1D DP遞推

codeforce404 D. Minesweeper 1D DP遞推

給定一個一維矩陣,其中包含‘1’、‘2’、‘0’、‘*’、‘?’,掃雷小遊戲——1表示左右有一個雷,2表示左右都有雷,0表示左右都沒有雷,*表示雷,?表示未知,求其中有多少種可能的情況,若該圖自相矛盾也輸出0

dp[L][2][2]表示檔期位置為L,當前位置若是雷則為1,否則為0,下一位置若是雷則為1,否為0

遞推時需要判斷:根據不同情況分類討論

#include<bits/stdc++.h>
using namespace std;
const int MAX=1e6+5;
const long long MOD=1e9+7;
char s[MAX];
int L;
long long dp[MAX][2][2];
int main()
{
    while(~scanf("%s",s+1))
    {
        memset(dp,0,sizeof(dp));
        L=strlen(s+1);dp[0][0][0]=dp[0][0][1]=1;
        for(int i=1;i<=L;++i)
        {
            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 if(s[i]=='*')
            {
                dp[i][1][0]=(dp[i-1][1][1]+dp[i-1][0][1])%MOD;
                dp[i][1][1]=dp[i][1][0];
            }
            else
            {
                dp[i][0][0]=(dp[i-1][1][0]+dp[i-1][0][0])%MOD;
                dp[i][0][1]=dp[i][0][0];
                dp[i][1][0]=(dp[i-1][0][1]+dp[i-1][1][1])%MOD;
                dp[i][1][1]=dp[i][1][0];
            }
        }
        long long ans=0;
        if(s[L]=='0') ans=dp[L-1][0][0];
        else if(s[L]=='1') ans=dp[L-1][1][0];
        else if(s[L]=='2') ans=0;
        else if(s[L]=='*') ans=(dp[L-1][0][1]+dp[L-1][1][1])%MOD;
        else ans=(dp[L-1][0][0]+dp[L-1][1][0]+dp[L-1][0][1]+dp[L-1][1][1])%MOD;
        printf("%lld\n",ans);
    }
    return 0;
}