洛谷 2622 关灯问题Ⅱ
状压DP练习题
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cctype> #include <cmath> inline void read(int & x) { int k = 1; x = 0; char c = getchar(); while (!isdigit(c)) if (c == '-') c = getchar(), k = -1; else c = getchar(); while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar(); x *= k; } int n, m, x, cnt = 0, y, s = 1, u; int a[110][12], tot = 0, f[50505], d[50505], v[50505], dp[50550]; signed main() { read(n), read(m); for (int i = 1; i <= m; ++i) for (int j = 1; j <= n; ++j) read(a[i][j]); for (int i = 0; i <= 50505; ++i) dp[i] = 1199887766; dp[(1 << n) - 1] = 0; for (int i = (1 << n) - 1; i >= 0; --i) { for (int j = 1; j <= m; ++j) { int newnode = i; for (int q = 1; q <= n; ++q) { if (a[j][q] == 0) continue; if (!((1 << (q - 1)) & i) && a[j][q] == -1) newnode ^= (1 << (q - 1)); if (((1 << (q - 1)) & i) && a[j][q] == 1) newnode ^= (1 << (q - 1)); } dp[newnode] = std::min(dp[newnode], dp[i] + 1); } } printf("%d", dp[0] == 1199887766 ? -1 : dp[0]); return 0; }