SCI2005扫雷

[SCOI2005]扫雷MINE

https://ac.nowcoder.com/acm/problem/20241

题意:
那是在一个n×m的矩阵里面有一些雷,要你根据一些信息找出雷来。这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字表示和它8连通的格子里面雷的数目。现在棋盘是n×2的,第一列里面某些格子是雷,而第二列没有雷,如下图:
图片说明

由于第一列的雷可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息确定第一列雷有多少种摆放方案。

解题思路:
如果是dp的话,需要设置一个状态能同时表示3个位置,也就是dp[i][a][b][c],a、b、c的状态分别表示i-1、i、i+1行有没有雷。根据经验只需要表示i和i+1行的状态就可以了。
于是就分类讨论转移方程

#include <bits/stdc++.h>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=a;i>=b;i--)
#define me0(a) memset(a,0,sizeof(a))
#define me1(a) memset(a,-1,sizeof(a))
#define op freopen("in.txt", "r", stdin)
#define pii pair<int,int>
#define mp(x,y) make_pair(x,y)
using namespace std;
const int INF = 0x3f3f3f3f;
typedef long long LL;
void read(int& val) { int x = 0; int bz = 1; char c; for (c = getchar(); (c<'0' || c>'9') && c != '-'; c = getchar()); if (c == '-') { bz = -1; c = getchar(); }for (; c >= '0' && c <= '9'; c = getchar()) x = x * 10 + c - 48; val = x * bz; }
const int mod=1e9+7;
const int maxn = 1e5+7;

int n;
LL dp[maxn][2][2];
int a[maxn],b[maxn];//b代表实际上有没有雷

int main(){
    read(n);
    fo(i,1,n) read(a[i]);
    dp[0][0][1]=dp[0][0][0]=1;

    fo(i,1,n){
        if(a[i]==0){
            dp[i][0][0]+=dp[i-1][0][0];
        }
        else if(a[i]==1){
            dp[i][0][0]+=dp[i-1][1][0];//b[i-1]=1
            dp[i][1][0]+=dp[i-1][0][1];//b[i]=1
            dp[i][0][1]+=dp[i-1][0][0];//b[i+1]=1
        }
        else if(a[i]==2){
            dp[i][1][1]+=dp[i-1][0][1];//b[i-1]=0
            dp[i][0][1]+=dp[i-1][1][0];//b[i]=0
            dp[i][1][0]+=dp[i-1][1][1];//b[i+1]=0
        }
        else{
            dp[i][1][1]+=dp[i-1][1][1];
        }
    }
    LL ans=0;
    fo(i,0,1) ans+=dp[n][i][0];
    printf("%lld\n",ans);
    return 0;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务