题目大意:有一些人可以站在mxn的格子里面,有一些格子不能站人,不能站在相邻格子,有几种站法。
https://ac.nowcoder.com/acm/problem/15034
这题就是一道很基本的状态压缩DP,时间复杂度是O(m2^n2^n)对于m=n=12刚好不会TLE。
一开始没注意审题,注意支持多组数据。
ll doit(int n, int m, VI& grid) {
int mask_size = (1 << m);
VVL dp(n + 1, VL(mask_size, 0));
dp[0][0] = 1;
for (int row = 0; row < n; ++row) {
int now = row + 1;
int prev = row;
for (int new_mask = 0; new_mask < mask_size; ++new_mask) {
if (new_mask & (new_mask >> 1)) continue;
bool fine = true;
REP(j, m) {
if (new_mask & (1 << j)) {
if ((grid[row] & (1 << j)) == 0) {
fine = false;
}
}
}
if (!fine) continue;
for (int old_mask = 0; old_mask < mask_size; ++old_mask) {
if (old_mask & new_mask) continue;
dp[now][new_mask] += dp[prev][old_mask];
dp[now][new_mask] %= MOD;
}
}
}
ll ans = 0;
REP(i, mask_size) {
ans += dp[n][i];
ans %= MOD;
}
return ans;
}
int main(int argc, char* argv[]) {
/* Do not use for codejam. */
/* ios_base::sync_with_stdio(false); cin.tie(NULL); */
int n, m;
while (scanf("%d%d",&n,&m) == 2) {
VI grid(n, 0);
REP(i,n){
REP(j,m){
readint(curr);
grid[i] = grid[i] * 2 + curr;
}
}
printlong(doit(n,m,grid));
}
return 0;
} 
京公网安备 11010502036488号