Title Description
N conventional lamps, and m buttons. Each button can simultaneously control the lamp n - i-button is pressed, all lamps have an effect. For the first pressed i j lamp, is one of the 3 following effects: If A [i] [j] is 1, then when this lamp when opened, shut it off, otherwise no matter; If -1 then, if this lamp is off, then open it, otherwise no matter; if it is 0, regardless of whether these lights on, do not care.
Now these lights are open, given all the switches to control the effect of all the lamps, inquire at least a few Yaoan button to switch off all.
Input Format
The first two rows of two numbers, nm
Subsequently m rows, each row number n, a [i] [j] indicates the effect of the i-th switch of j-th light.
Output Format
An integer representing the minimum number press the button. If there is no way to make it all off, output -1
Entry
3
2
1 0 1
-1 1 0
Export
2
Description / Tips
For 20% of the data, no solution can score output.
Data for 20%, n <= 5
20% to the data, m <= 20
The above data points may overlap.
Data for 100% <= n 10, m <= 100
answer
- Obviously shaped pressure DP
- N = 10 lights up, i.e., (1 << 10) --1 states
- Start enumeration from the fully open state, until the fully closed state;
for each state, the enumeration switch;
for each switch, find the state after the switch changes
the[Status changes after] dp = min (dp [the state change], dp [to a state just] + 1);(Just as the state, only a change of state of the switch is to change after) - The last answer is dp [0]
AC-Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
const int mod = 1e9;
int a[101][11];
int dp[1 << 10];
int main() {
ios;
int n, m;
while (cin >> n >> m) {
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
cin >> a[i][j];
memset(dp, 0x3f, sizeof(dp));
dp[(1 << n) - 1] = 0;
for (int i = (1 << n) - 1; i >= 0; i--) { // 枚举状态
for (int j = 1; j <= m; j++) { // 枚举开关
int now = i;
for (int k = 1; k <= n; k++) { // 枚举灯
if (!a[j][k]) continue;
else if (a[j][k] == 1 and (i & (1 << k - 1)))
now ^= (1 << (k - 1));
else if (a[j][k] == -1 and !(i & (1 << k - 1)))
now ^= (1 << k - 1);
}
dp[now] = min(dp[now], dp[i] + 1); // 从 i 状态,按一次开关(j)得到了 now 状态
}
}
cout << (dp[0] == 0x3f3f3f3f ? -1 : dp[0]) << endl;
}
}