• 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 }
  • 相关阅读:
    [bzoj1096][ZJOI2007]仓库建设
    [bzoj1010][HNOI2008]玩具装箱
    [bzoj2301][HAOI2011]Problem b
    [HDU1695]GCD
    [SDOI2006] 保安站岗
    [TJOI2007] 调整队形
    Luogu_1944 最长括号匹配
    [USACO07NOV] Milking Time
    [USACO13FEB] Tractor
    [模板] 一些要复习的模板
  • 原文地址:https://www.cnblogs.com/wangyiming/p/9159413.html
Copyright © 2020-2023  润新知