题目描述
相信大家都玩过扫雷的游戏。那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来。
万圣节到了 ,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字 表示和它8连通的格子里面雷的数目。
现在棋盘是n×2的,第一列里面某些格子是雷,而第二列没有雷,如下图: 由于第一列的雷可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息确定第一列雷有多少种摆放方案。

输入描述:
第一行为N,第二行有N个数,依次为第二列的格子中的数。(1 ≤ N ≤ 10000)

输出描述:
一个数,即第一列中雷的摆放方案数。
题解
设四维数组f[N][2][2][2],一维第二列位置,二维三维四维存i-1,i,i+1是否有雷
方程:
1.a[i]为0
图片说明

2.a[i]为1
图片说明
图片说明
图片说明

3.a[i]为2
图片说明
图片说明
图片说明

4.a[i]为3
图片说明

最后
如果a[n]=0,ans=f[n][0][0][0]
如果a[n]=1,ans=f[n][1][0][0]+f[n][0][1][0];
如果a[n]=2,ans=f[n][1][1][0];
如果a[n]=3,无解
代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define lowbit(x) x&(-x)
#define iter set<int>::iterator

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;

const int N = 1e5 + 5;
const int mod = 1e4 + 7;
const int INF = 0x3f3f3f3f;
const int dir[4][2]={-1,0,1,0,0,-1,0,1};

ll qpow(ll x,ll y){
    ll ans=1,t=x;
    while(y>0){
        if(y&1)ans*=t,ans%=mod;
        t*=t,t%=mod;
        y>>=1;
    }
    return ans;
}

int a[10001];
int f[10001][2][2][2];
void solve(){
    int n;cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    f[0][0][0][0]=f[0][0][0][1]=1;
    for(int i=1;i<=n;i++){
        if(!a[i])f[i][0][0][0]=f[i-1][0][0][0]+f[i-1][1][0][0];
        if(a[i]==1){
            f[i][1][0][0]=f[i-1][0][1][0]+f[i-1][1][1][0];
            f[i][0][1][0]=f[i-1][0][0][1]+f[i-1][1][0][1];
            f[i][0][0][1]=f[i-1][0][0][0]+f[i-1][1][0][0];
        }
        if(a[i]==2){
            f[i][1][1][0]=f[i-1][0][1][1]+f[i-1][1][1][1];
            f[i][1][0][1]=f[i-1][0][1][0]+f[i-1][1][1][0];
            f[i][0][1][1]=f[i-1][0][0][1]+f[i-1][1][0][1];
        }
        if(a[i]==3)f[i][1][1][1]=f[i-1][0][1][1]+f[i-1][1][1][1];
    }
    int ans=0;
    if(!a[n])ans=f[n][0][0][0];
    if(a[n]==1)ans=f[n][1][0][0]+f[n][0][1][0];
    if(a[n]==2)ans=f[n][1][1][0];
    cout<<ans;
}
int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    //int t;cin>>t;
    //while(t--)solve(),cout<<endl;
    solve();
    return 0;
}