Codeforces Round #237 (Div. 2) D. Minesweeper 1D(多维DP)(好题)

题目链接
在这里插入图片描述
在这里插入图片描述
题意:一维的扫雷,"*"表示雷,“0”表示左右两边没有雷,“1”表示左右两边有一个雷,“2”表示左右两个都是雷,“?”表示不确定任意填(但是需要满足左右两个方格内的条件),先求方案数
思路:dp【i】【0】代表i位有雷,左右任意,dp【i】【1】代表i位无雷,左右都无雷;dp【i】【2】代表i位无雷,左边有雷,右边无雷;dp【i】【3】代表i位无雷,左边无雷,右边有雷;dp【i】【4】代表i位无雷,左右边都有雷。可以仔细思考一下状态转移,很好的题,虽然一开始我不会QAQ

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e6+5; 
const int mod=1e9+7;
char s[maxn];
ll dp[maxn][5],ans=0;
int main()
{
	scanf("%s",s+1);
	int len=strlen(s+1);
	dp[0][1]=dp[0][3]=1;
	for(int i=1;i<=len;++i)
	{
		if(s[i]=='0') dp[i][1]=(dp[i-1][2]+dp[i-1][1])%mod;
		if(s[i]=='1') dp[i][2]=dp[i-1][0]%mod,dp[i][3]=(dp[i-1][1]+dp[i-1][2])%mod;
		if(s[i]=='2') dp[i][4]=dp[i-1][0]%mod;
		if(s[i]=='*') dp[i][0]=((dp[i-1][0]+dp[i-1][3])%mod+dp[i-1][4])%mod;
		if(s[i]=='?') {
			dp[i][1]=(dp[i-1][2]+dp[i-1][1])%mod;
			dp[i][2]=dp[i-1][0]%mod,dp[i][3]=(dp[i-1][1]+dp[i-1][2])%mod;
			dp[i][4]=dp[i-1][0]%mod;
			dp[i][0]=((dp[i-1][0]+dp[i-1][3])%mod+dp[i-1][4])%mod;
		}
	}
	printf("%lld\n",((dp[len][0]+dp[len][1])%mod+dp[len][2])%mod);
}
发布了391 篇原创文章 · 获赞 1 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42479630/article/details/105374998