白书的插头dp入门级题目,看了很久差不多懂了但是感觉自己写起来还是挺有难度的
题意:求用1∗2木块将给出的n∗m大小的矩阵填满的方法总数
用dp[i][j]表示第i块位置,并且该位置对应的行数的状态为j的时候的总情况数。
对于每个阶段的每个状态有3种转移方式
(1)不放
(2)竖放
(3)横放
注意第一喂要用滚动数组优化内存
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define rep(i, j, k) for(int i = j; i <= k; i++)
using namespace std;
long long n, m, f[2][1 << 11];
int cur;
void update (int a, int b)
{
if (b & (1 << m))
f[cur][b ^ (1 << m)] += f[cur ^ 1][a]; // ?
}
int main ()
{
while (cin >> n >> m)
{
if (m > n)
swap (n, m);
cur = 0;
memset (f, 0, sizeof (f));
f[0][ ( 1 << m) - 1] = 1;
rep (i, 1, n)
rep (j, 1, m)
{
cur ^= 1;
memset (f[cur], 0, sizeof (f[cur]));
rep (k, 0, (1 << m) - 1)
{
update (k, k << 1);
if (i > 1 && !(k & (1 << m - 1)))
update (k, (k << 1) ^ (1 << m) ^ 1);
if (j > 1 && !(k & 1))
update (k, (k << 1) ^ 3);
}
}
cout << f[cur][ (1 << m) - 1] << endl;
}
return 0;
}