PKU_campus_2017_K Lying Island

思路:

题目链接http://poj.openjudge.cn/practice/C17K/

状压dp。dp[i][j]表示第i - k人到第i人的状态为j的情况下前i人中最多有多少好人。

实现:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int dp[2][2049];
 4 struct node
 5 {
 6     int type, id1, id2;
 7     bool f1, f2;
 8 };
 9 node a[5001];
10 bool same(bool a, bool b)
11 {
12     return (a && b) || (!a && !b);
13 }
14 int main()
15 {
16     int t, n, k;
17     cin >> t;
18     while (t--)
19     {
20         memset(dp, 0, sizeof dp);
21         cin >> n >> k;
22         string s;
23         getchar();
24         for (int i = 1; i < n; i++)
25         {
26             getline(cin, s);
27             string tmp;
28             stringstream ss(s);
29             vector<string> v;
30             while (ss >> tmp) v.push_back(tmp);
31             if (v[2][0] == 'I')
32             {
33                 a[i].type = 2;
34                 a[i].id1 = atoi(v[4].c_str());
35                 a[i].id2 = atoi(v[10].c_str());
36                 a[i].f1 = v[7] == "good" ? true : false;
37                 a[i].f2 = v[13] == "good" ? true : false;
38             }
39             else
40             {
41                 a[i].type = 1;
42                 a[i].id1 = atoi(v[3].c_str());
43                 a[i].f1 = v[6] == "good" ? true : false;
44             }
45         }
46         
47         int msk = (1 << k + 1) - 1;
48         dp[0][1] = 1;
49         for (int i = 1; i < n; i++)
50         {
51             memset(dp[i & 1], 0, sizeof dp[i & 1]);
52             for (int j = 0; j < 1 << k + 1; j++)
53             {
54                 if (i < k + 1 && j >= 1 << i) continue;
55                 int tmp = j << 1 & msk;
56                 dp[i & 1][tmp] = max(dp[i & 1][tmp], dp[i - 1 & 1][j]);
57                 if (a[i].type == 1)
58                 {
59                     int p1 = i - a[i].id1;
60                     if (same(a[i].f1, j >> p1 & 1))
61                     {
62                         dp[i & 1][tmp | 1] = max(dp[i & 1][tmp | 1], dp[i - 1 & 1][j] + 1);
63                     }
64                 }
65                 else
66                 {
67                     int p1 = i - a[i].id1, p2 = i - a[i].id2;
68                     bool g1 = j >> p1 & 1, g2 = j >> p2 & 1;
69                     if (!(same(a[i].f1, g1) && !same(a[i].f2, g2)))
70                         dp[i & 1][tmp | 1] = max(dp[i & 1][tmp | 1], dp[i - 1 & 1][j] + 1);
71                 }
72             }
73         }
74         int ans = 0;
75         for (int i = 0; i < 1 << k + 1; i++)
76             ans = max(ans, dp[n - 1 & 1][i]);
77         cout << ans << endl;
78     }
79     return 0;
80 }
原文地址:https://www.cnblogs.com/wangyiming/p/9159413.html