思路:
状压dp,只需记录m位状态即可。
实现:
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 const int MAXN = 11, MAXM = 11; 5 typedef pair<int, int> pii; 6 typedef long long ll; 7 ll dp[MAXN + 1][MAXM + 1][1 << MAXM + 1]; 8 int n, m; 9 10 pii next(int x, int y) 11 { 12 pii res; 13 res.first = y == m - 1 ? x + 1 : x; 14 res.second = y == m - 1 ? 0 : y + 1; 15 return res; 16 } 17 18 int main() 19 { 20 while (cin >> n >> m, n || m) 21 { 22 memset(dp, 0, sizeof dp); 23 dp[n][0][0] = 1; 24 for (int i = n - 1; i >= 0; i--) 25 { 26 for (int j = m - 1; j >= 0; j--) 27 { 28 for (int k = 0; k < 1 << m; k++) 29 { 30 pii tmp = next(i, j); 31 if (k >> j & 1) 32 dp[i][j][k] = dp[tmp.first][tmp.second][k & ~(1 << j)]; 33 else 34 { 35 dp[i][j][k] = dp[tmp.first][tmp.second][k | 1 << j]; 36 if (j < m - 1 && !(k >> j + 1 & 1)) 37 { 38 tmp = next(i, j + 1); 39 dp[i][j][k] += dp[tmp.first][tmp.second][k]; 40 } 41 } 42 } 43 } 44 } 45 cout << dp[0][0][0] << endl; 46 } 47 return 0; 48 }