题目大意:Nx2列的扫雷,第二列没有雷,并且第二列每个数代表周围八个里面有多少雷。给定第二列的数,问有几种排法。

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

很经典的状态压缩DP。可以认为有一个01数组,然后知道每连续三位的总和。问有多少种方法。

====

仔细一想,其实如果知道第一第二个是多少就可以依次推出所有的雷,所以直接就是4*N次。答案最大也就是4(估计还达不到)。

int N;
#define MAXN 10005
int cnt[MAXN];
ll dp[2][2][2];
ll doit() {
  // dp[i][curr][nxt] stores the count.
  dp[0][0][0] = (cnt[0] == 0);
  dp[0][0][1] = dp[0][1][0] = (cnt[0] == 1);
  dp[0][1][1] = (cnt[0] == 2);
  FOR(i,1,N-1){
    REP(curr,2){
      REP(nxt,2){
        dp[i%2][curr][nxt]=0;
        REP(prev,2){
          if(prev+nxt+curr==cnt[i]){
            dp[i%2][curr][nxt]+=dp[1-i%2][prev][curr];
          }
        }
      }
    }
  }
  ll ans = dp[1-N%2][0][0]+dp[1-N%2][1][0];
  return ans;
}
int main(int argc, char* argv[]) {
  while (scanf("%d",&N)==1){
    read(cnt, N);
    print(doit());
  }
  return 0;
}