[HDU5965]扫雷

[HDU5965]扫雷

题目大意:

一个(3 imes n(nle10000))的扫雷,第(2)排没有雷。告诉你第(2)排上的数,问有几种埋雷的方案?

思路:

动态规划。

(1,3)两排的雷全部往左移一格,即第(2)排上第(i)列的数只和(1,3)两排第(i-2,i-1,i)列的雷有关。

(f[i][j][k])表示前(i)列,第(i)列有(k)个雷,第(i-1)列有(j)个雷的方案数。

转移十分显然。

时间复杂度(mathcal O(n))

源代码:

#include<cstdio>
#include<cctype>
#include<cstring>
inline int getint() {
	register char ch;
	while(!isdigit(ch=getchar()));
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return x;
}
const int N=10001,mod=1e8+7;
char s[N+1];
int f[N][3][3];
int main() {
	for(register int T=getint();T;T--) {
		memset(f,0,sizeof f);
		scanf("%s",&s[1]);
		const int n=strlen(&s[1]);
		for(register int i=1;i<=n;i++) s[i]-='0';
		f[0][0][0]=1;
		if(s[1]>=1) f[0][0][1]=2;
		if(s[1]>=2) f[0][0][2]=1;
		for(register int i=1;i<=n;i++) {
			for(register int j=0;j<3;j++) {
				for(register int k=0;k<3;k++) {
					if(f[i-1][j][k]==0||j+k>s[i]||s[i]>2+j+k) continue;
					(f[i][k][s[i]-j-k]+=f[i-1][j][k])%=mod;
					if(s[i]-j-k==1) (f[i][k][1]+=f[i-1][j][k])%=mod;
				}
			}
		}
		int ans=0;
		for(register int i=0;i<3;i++) {
			(ans+=f[n][i][0])%=mod;
		}
		printf("%d
",ans);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/skylee03/p/9430674.html