Minesweeper 1D

                                          Minesweeper 1D

题目描述:

            题目讲述的是一个一维的扫雷游戏,输入一个给定的字符串,然后这个字符串当中含有五种字符,分别为'0','1','2','*'以及'?'。

            '0'表示这个格子相邻的格子没有地雷,'1'表示这个格子相邻的格子含有一个地雷,'2'表示这个格子相邻的格子含有两个地雷,'*'表示这个格子是地雷,'?'表示的是未知情况,可能是以上的四种字符之中的其中一种。

            题目让我们求的是,所有'?'换成以上任意四种字符后,总共有多少种方案,使得这个字符串满足扫雷的游戏规则。

题目分析:

            这个题目是一道DP的题目,我们的策略是根据前面已经枚举得到的情况推出当前网格可能的情况,由于前面的格子是什么我们已经经过前面的运算已经推导出来,所以我需要枚举的是当前格子是什么以及下一个格子是什么。

            那么对于当前格子,主要存在三种状态,我们分别记为0,1和2。

            0状态表示当前格子没有地雷以及下一个格子没有地雷。

            1状态表示当前格子没有地雷以及下一个格子存在地雷。

            2状态表示当前格子是地雷,下一个格子的情况不可知(这是因为下一个格子既可以存在地雷,也可以不存在地雷)

            那么根据上述定义,我们初始化dp[0][0]=dp[0][1]=1,因为我们默认字符串的第0个字符没有地雷,但是我们不知道第1个字符是否存在地雷,因此存在这样的两种状态。

            那么状态转移很明显就可以写出来:

            如果第i个格子是0的话,那么证明上一个格子以及下一个格子没有地雷,因此dp[i][0]=dp[i][0]+dp[i-1][0]

            如果第i个格子是1的话,那么证明上一个格子存在地雷或者下一个格子存在地雷。

            因此dp[i][0]=dp[i-1][2],dp[i][1]=dp[i-1][0]

            如果第i个格子是2的话,那么证明上一个格子和下一个格子都存在地雷,因此dp[i][1]=dp[i][1]+dp[i][2]

            如果第i个格子存在地雷的话,那么状态转移方程为:dp[i][2]=dp[i][2]+dp[i-1][1]+dp[i-1][2]

            至于如果第i个字符是'?'的话,以上四种情况都满足。

代码:

#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <cstdlib>
#include <stdlib.h>
#include <cmath>
#include <math.h>
#include <algorithm>
#include <string>
#include <cstring>
#include <string.h>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#define reg register
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define lowbit(x) (x&(-x))
#define mod 1000000007
using namespace std;
const int Maxn=1e6+5;
char st[Maxn];
int dp[Maxn][5];
int main()
{
	scanf("%s",st+1);
	int n=strlen(st+1);
	dp[0][0]=dp[0][1]=1;
	for (reg int i=1;i<=n;i++)
	{
		if (st[i]=='0' || st[i]=='?') dp[i][0]=(dp[i][0]+dp[i-1][0])%mod;
		if (st[i]=='1' || st[i]=='?')
		{
			dp[i][1]=(dp[i][1]+dp[i-1][0])%mod;
			dp[i][0]=(dp[i][0]+dp[i-1][2])%mod; 
		}
		if (st[i]=='2' || st[i]=='?') dp[i][1]=(dp[i][1]+dp[i-1][2])%mod;
		if (st[i]=='*' || st[i]=='?')
		{
			dp[i][2]=(dp[i][2]+dp[i-1][2])%mod;
			dp[i][2]=(dp[i][2]+dp[i-1][1])%mod;
		}
	}
	int ans=(dp[n][0]+dp[n][2])%mod;
	printf("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36679229/article/details/88702469