poj2411 Mondriaan's Dream

思路:

状压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 }

猜你喜欢

转载自www.cnblogs.com/wangyiming/p/9111393.html