题目传送门
1 /*
2 贪心:按照0或1开头,若不符合,选择后面最近的进行交换。然后选取最少的交换次数
3 */
4 #include <cstdio>
5 #include <algorithm>
6 #include <cstring>
7 #include <string>
8 #include <cmath>
9 #include <vector>
10 #include <map>
11 #include <queue>
12 using namespace std;
13
14 const int MAXN = 22 + 10;
15 const int INF = 0x3f3f3f3f;
16 int a[MAXN], b[MAXN], c[MAXN];
17
18 int main(void) //UVALive 6832 Bit String Reordering
19 {
20 // freopen ("A.in", "r", stdin);
21
22 int n, m;
23 while (scanf ("%d%d", &n, &m) == 2)
24 {
25 for (int i=1; i<=n; ++i) {scanf ("%d", &a[i]); c[i] = a[i];}
26 for (int i=1; i<=m; ++i) scanf ("%d", &b[i]);
27
28 int cnt1 = 0, cnt2 = 0; int now = 0; int p = 0;
29 bool ok1 = true, ok2 = true;
30 for (int i=1; i<=m && ok1; ++i)
31 {
32 for (int j=1; j<=b[i]; ++j)
33 {
34 if (a[p+j] != now)
35 {
36 int k = p + j;
37 while (k <= n && a[k] != now) k++;
38 if (k == n+1 || a[k] != now) {ok1 = false; break;}
39 cnt1 += k - (p + j);
40 swap (a[k], a[p+j]);
41 }
42 }
43 p += b[i]; now = 1 - now;
44 }
45
46 now = 1; p = 0;
47 for (int i=1; i<=m && ok2; ++i)
48 {
49 for (int j=1; j<=b[i]; ++j)
50 {
51 if (c[p+j] != now)
52 {
53 int k = p + j;
54 while (k <= n && c[k] != now) k++;
55 if (k == n+1 || c[k] != now) {ok2 = false; break;}
56 cnt2 += k - (p + j);
57 swap (c[p+j], c[k]);
58 }
59 }
60 p += b[i]; now = 1 - now;
61 }
62
63 // printf ("%d %d
", cnt1, cnt2);
64 if (!ok1) printf ("%d
", cnt2);
65 else if (!ok2) printf ("%d
", cnt1);
66 else printf ("%d
", min (cnt1, cnt2));
67 }
68
69 return 0;
70 }