Topcoder SRM 722 Div1 600Pts DominoTiling(簡單插頭DP)
阿新 • • 發佈:2018-01-29
lap 就是 ont 要求 net esp $1 true mes
題意 給定一個$12*12$的矩陣,每個元素是‘.‘或‘X‘。現在要求$1*2$的骨牌鋪滿整個矩陣,
‘X‘處不能放置骨牌。求方案數。
這道題其實和 Uva11270 是差不多的,就是加了一些條件。
那麽分類討論的時候情況裏面要加點東西:
1、當前格子為‘X‘,這個時候這個格子上不能放置骨牌,那麽狀態只能轉移到下一位,註意最後一位應該變成$1$
因為這個格子是被填充的。
2、當前格子為‘.‘,這個時候這個格子上可以往左邊橫著放骨牌,要求$grid[i][j-1]為‘.‘$;
也可以往上面放骨牌,要求$grid[i-1][j]為‘.‘$;
也可以不放。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; LL f[2][(1 << 14) + 5]; int n, m; int x; inline void up(int a, int b){ if (b & (1 << m)) f[x][b ^ (1 << m)] += f[x ^ 1][a]; } class DominoTiling { public: long long count(vector<string> grid) { n = (int)grid.size(); m = (int)grid[0].size(); memset(f, 0, sizeof f); x = 0; f[x][(1 << m) - 1] = 1; rep(i, 0, n - 1){ rep(j, 0, m - 1){ x ^= 1; memset(f[x], 0, sizeof f[x]); if (grid[i][j] == ‘X‘){ rep(k, 0, (1 << m) - 1) up(k, (k << 1) ^ 1); continue; } rep(k, 0, (1 << m) - 1){ up(k, k << 1); if (i && !(k & (1 << (m - 1))) && grid[i - 1][j] == ‘.‘) up(k, (k << 1) ^ (1 << m) ^ 1); if (j && !(k & 1) && grid[i][j - 1] == ‘.‘) up(k, (k << 1) ^ 3); } } } return f[x][(1 << m) - 1]; } };
Topcoder SRM 722 Div1 600Pts DominoTiling(簡單插頭DP)