硬木地板

這就是個業界毒瘤......50行的狀壓DP。html

題意:用(1*2的棋子)和(2*2挖掉1*1的棋子)鋪滿n * m的方案數。n,m<=9。ide

提及來跟以前那個廣場鋪磚問題幾乎如出一轍,而後再借鑑芯片中的pre思想便可。函數

可是呢......特殊狀況一個接一個,硬是打了一個小時才寫出來。spa

在DFS轉移的時候,因爲要知足"鋪滿"性質,咱們要保證i - 1行所有填滿。code

通常轉移的時候只要注意(x - 1, y - 1)便可,而後頭尾要特判。htm

提及來簡單,寫起來一個DFS函數95行可不是說着玩的......blog

而後就很高興的A了。記得開long longget

  1 #include <cstdio>
  2 #include <algorithm>
  3 
  4 typedef long long LL;
  5 const int N = 10;
  6 
  7 LL f[N][1200], ans;
  8 int pre, m;
  9 
 10 void DFS(int x, int y, int ns) {
 11     //printf("DFS : x = %d  y = %d  ns = %d  pre = %d \n", x, y, ns, pre);
 12     if(y == m) {
 13         f[x][ns] += ans;
 14         //printf("DFS : f[%d][%d] = %d \n", x, ns, f[x][ns]);
 15         return;
 16     }
 17     if(y > m) {
 18         return;
 19     }
 20     int temp = pre;
 21     if(!y) {
 22         DFS(x, y + 1, ns); // space
 23         if(!(pre & 1)) {
 24             pre |= 1;
 25             DFS(x, y + 1, ns | 1); // |
 26             pre = temp;
 27         }
 28         return;
 29     }
 30     if(y + 1 == m) {
 31         if(!((pre >> (y - 1)) & 1)) {
 32             if(!((pre >> y) & 1)) {
 33                 pre |= (1 << y);
 34                 DFS(x, y + 1, ns | (1 << y)); // ^|
 35                 pre = temp;
 36                 if(!((ns >> (y - 1)) & 1)) {
 37                     pre |= (1 << y);
 38                     DFS(x, y + 1, ns | (1 << (y - 1))); // |^
 39                     pre = temp;
 40                 }
 41                 return;
 42             }
 43             else {
 44                 if(!((ns >> (y - 1)) & 1)) {
 45                     DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // |_
 46                 }
 47                 return;
 48             }
 49         }
 50         if(!((pre >> y) & 1)) {
 51             pre |= (1 << y);
 52             DFS(x, y + 1, ns | (1 << y)); // |
 53             pre = temp;
 54             if(!((ns >> (y - 1)) & 1)) {
 55                 pre |= (1 << y);
 56                 DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // _|
 57                 pre = temp;
 58             }
 59             return;
 60         }
 61         DFS(x, y + 1, ns); // space
 62         if(!((ns >> (y - 1)) & 1)) {
 63             DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // --
 64         }
 65         return;
 66     }
 67     if((pre >> y) & 1) {
 68         if(!((pre >> (y - 1)) & 1)) {
 69             if((ns >> (y - 1)) & 1) {
 70                 return;
 71             }
 72             DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // |_
 73             return;
 74         }
 75         if(!((ns >> (y - 1)) & 1)) {
 76             DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // --
 77         }
 78         DFS(x, y + 1, ns); // space
 79         return;
 80     }
 81     if(!((pre >> (y - 1)) & 1)) {
 82         pre |= (1 << y);
 83         DFS(x, y + 1, ns | (1 << y)); // ^|
 84         pre = temp;
 85         if(!((ns >> (y - 1)) & 1)) {
 86             DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // |_
 87             pre |= (1 << y);
 88             DFS(x, y + 1, ns | (1 << (y - 1))); // |^
 89             pre = temp;
 90         }
 91         return;
 92     }
 93     DFS(x, y + 1, ns); // space
 94     pre |= (1 << y);
 95     DFS(x, y + 1, ns | (1 << y)); // |
 96     pre = temp;
 97     if(!((ns >> (y - 1)) & 1)) {
 98         pre |= (1 << y);
 99         DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // _|
100         pre = temp;
101         DFS(x, y + 1, ns | (1 << y) | (1 << (y - 1))); // --
102     }
103     return;
104 }
105 
106 int main() {
107     int n;
108     scanf("%d%d", &n, &m);
109     if(n == 1 || m == 1) {
110         if(std::max(m, n) & 1) {
111             printf("0");
112         }
113         else {
114             printf("1");
115         }
116         return 0;
117     }
118 
119     // prework
120     int lm = 1 << m;
121     f[0][lm - 1] = 1;
122 
123     for(int i = 1; i <= n; i++) {
124         for(int j = 0; j < lm; j++) { // state of i - 1
125             //printf("f[%d][%d] = %d \n", i - 1, j, f[i - 1][j]);
126             pre = j;
127             ans = f[i - 1][j];
128             DFS(i, 0, 0);
129         }
130     }
131     printf("%lld", f[n][lm - 1]);
132     return 0;
133 }
AC代碼

某大佬把轉移處理成了鄰接表而後求方案數,%%%%it

相關文章
相關標籤/搜索