题目描述
输入输出格式
输入格式:
第一行为N,第二行有N个数,依次为第二列的格子中的数。(1<= N <= 10000)
输出格式:
一个数,即第一列中雷的摆放方案数。
输入输出样例
输入样例#1: 复制
2 1 1
输出样例#1: 复制
2
一道很小型的状压,我们用一个二位二进制记录到当前行的时候,当前行的下一格和当前行对应的格子是否为地雷。这样我们就可以根据信息递推状态转移方程,具体见代码:
#include<cstdio>
#define LL long long
#define For(i, a, b) for(register int i = a; i <= b; ++i)
using namespace std;
const int maxn = 1e4 + 5;
LL dp[maxn][5];
int num[maxn], now, n;
int main() {
scanf("%d", &n);
For(i, 1, n) scanf("%d", &num[i]);
dp[0][0] = dp[0][1] = 1;
For(i, 0, n - 1) {
For(k, 0, 3) {
now = dp[i][k];
int G = (k << 1 | 1) % 4, U = (k << 1) % 4;
if(num[i + 1] == 0 && !(k & 1) && !(k & 2))
dp[i + 1][U] += now;
if(num[i + 1] == 1) {
if(k & 2 && !(k & 1)) dp[i + 1][U] += now;
if(!(k & 2) && k & 1) dp[i + 1][U] += now;
if(!(k & 2) && !(k & 1)) dp[i + 1][G] += now;
}
if(num[i + 1] == 2) {
if(k & 2 && !(k & 1)) dp[i + 1][G] += now;
if(k & 1 && !(k & 2)) dp[i + 1][G] += now;
if((k & 3) == 3) dp[i + 1][U] += now;
}
if(num[i + 1] == 3) {
if((k & 3) == 3) dp[i + 1][G] += now;
}
}
//if(i == 0) dp[1][2] = dp[1][3] = 0;
}
printf("%lld", dp[n][0] + dp[n][2]);
return 0;
}
rockdu
没有帐号? 立即注册