题源:https://www.luogu.org/problemnew/solution/P1879
偏模板的状压dp题。
#include <bits/stdc++.h>
#define numm ch - 48
#define pd putchar(' ')
#define pn putchar('\n')
#define pb push_back
#define fi first
#define se second
#define fre1 freopen("1.txt", "r", stdin)
#define fre2 freopen("2.txt", "w", stdout)
typedef long long int ll;
typedef long long int LL;
using namespace std;
template<typename T>
void read(T &res) {
bool flag = false;
char ch;
while (!isdigit(ch = getchar())) (ch == '-') && (flag = true);
for (res = numm; isdigit(ch = getchar()); res = (res << 1) + (res << 3) + numm);
flag && (res = -res);
}
template<typename T>
void write(T x) {
if (x < 0)
putchar('-'), x = -x;
if (x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
//static auto _ = []() {
// ios::sync_with_stdio(false);
// cin.tie(0);
// return 0;
//}();
#pragma GCC optimize(3, "Ofast", "inline")
//
const int mod = 100000000;
int m, n;
int mp[13][13];
ll dp[13][4096] = {0};
int main() {
read(m), read(n);
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
read(mp[i][j]);
}
}
for (int j = 0; j < (1 << n); j++) {
for (int k = j, l = n; k > 0; k >>= 1, l--) {
if ((k & 1) && (!mp[1][l])) goto loop2;
}
if (j & (j << 1)) goto loop2;
if (j & (j >> 1)) goto loop2;
dp[1][j]++;
loop2:;
}
for (int i = 2; i <= m; i++) {
for (int j = 0; j < (1 << n); j++) {
for (int k = j, l = n; k > 0; k >>= 1, l--) {
if ((k & 1) && (!mp[i][l])) goto loop;
}
if (j & (j << 1)) goto loop;
if (j & (j >> 1)) goto loop;
for (int k = 0; k < (1 << n); k++) {
if (j & k) continue;
dp[i][j] =(dp[i][j] + dp[i - 1][k]) % mod;
}
loop:;
}
}
ll ans = 0;
for (int i = 0; i < (1 << n); i++) {
ans = (ans + dp[m][i]) % mod;
}
write(ans);
return 0;
}