zoukankan      html  css  js  c++  java
  • [Usaco2014 Open]Gold Fair Photography(hash)

    最近做了usaco2014 open的金组,果然美帝的题还是没有太简单啊QAQ,被每年的月赛骗了QAQ

    不过话说官方题解真心棒(虽然英文的啃得好艰难,我英语渣你们别鄙视我= =),标程超级优美QAQ

    按照标程打,学到了好多STL的用法= =(没办法,我c++底子弱)

    这道题嘛,可以发现对于每个区间,只要左边界确定,可能的集合就一共只有8种了

    考虑前缀和,发现若L~R为可行解,则对于所有种类的牛,有S[R]-S[L]=K或0

    如何防止枚举K,可以发现在该集合中B的s[L][bi]减去s[L][b0]就行了

    那么就hash,枚举集合B,求出hash值,直接做就行了

    CODE:(直接贴标程了,Map真的用的是神出鬼没啊QAQ)

    #include <iostream>
    #include <vector>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cassert>
    #include <map>
    
    using namespace std;
    
    #define MAXN 100010
    #define GROUPS 8
    
    int MB[MAXN][GROUPS];
    int MF[MAXN][GROUPS];
    int PS[MAXN][GROUPS];
    
    int main() {
      freopen("fairphoto.in", "r", stdin);
      freopen("fairphoto.out", "w", stdout);
    
      int N, K; cin >> N >> K;
      vector<pair<int, int> > A(N);
      for(int i = 0; i < N; i++) {
        cin >> A[i].first >> A[i].second;
        A[i].second--;
      }
      sort(A.begin(), A.end());
    
      /* Construct backstep masks */
      for(int i = 0; i < GROUPS; i++) {
        MB[0][i] = 1 << A[0].second;
      }
      for(int i = 1; i < N; i++) {
        int bt = 1 << A[i].second;
    
        MB[i][0] = bt;
        for(int j = 1; j < GROUPS; j++) {
          if(MB[i - 1][j] & bt) {
            MB[i][j] = MB[i - 1][j];
          } else {
            MB[i][j] = bt | MB[i - 1][j - 1];
          }
        }
      }
    
      /* Construct forward step masks */
      for(int i = 0; i < GROUPS; i++) {
        MF[N - 1][i] = 1 << A[N - 1].second;
      }
      for(int i = N - 2; i >= 0; i--) {
        int bt = 1 << A[i].second;
    
        MF[i][0] = bt;
        for(int j = 1; j < GROUPS; j++) {
          if(MF[i + 1][j] & bt) {
            MF[i][j] = MF[i + 1][j];
          } else {
            MF[i][j] = bt | MF[i + 1][j - 1];
          }
        }
      }
    
      /* Construct partial sums */
      for(int i = 0; i < N; i++) {
        memcpy(PS[i + 1], PS[i], sizeof(PS[i]));
        ++PS[i + 1][A[i].second];
      }
    
      int result = -1;
      for(int j = K - 1; j < GROUPS; j++) {
        vector<int> V(1 + GROUPS);
        map<vector<int>, int> cost_map;
    
        /* Compute the earliest starts for given masks
         * and normalized partial sums. */
        for(int i = N - 1; i >= 0; i--) {
          int base = -1;
          int m = V[GROUPS] = MF[i][j];
          if(__builtin_popcount(m) <= j) continue;
          for(int k = 0; k < GROUPS; k++) {
            if(m & 1 << k) {
              if(base == -1) {
                base = PS[i][k];
              }
              V[k] = PS[i][k] - base;
            } else {
              V[k] = PS[i][k];
            }
          }
          cost_map[V] = A[i].first;
        }
    
        /* Find best start points for each ending position. */
        for(int i = 0; i < N; i++) {
          int base = -1;
          int m = V[GROUPS] = MB[i][j];
          if(__builtin_popcount(m) <= j) continue;
          for(int k = 0; k < GROUPS; k++) {
            if(m & 1 << k) {
              if(base == -1) {
                base = PS[i + 1][k];
              }
              V[k] = PS[i + 1][k] - base;
            } else {
              V[k] = PS[i + 1][k];
            }
          }
    
          map<vector<int>, int>::iterator it = cost_map.find(V);
          if(it != cost_map.end() && it->second < A[i].first) {
            result = max(result, A[i].first - it->second);
          }
        }
      }
    
      cout << result << endl;
      return 0;
    }


  • 相关阅读:
    第九章
    第十章
    第八章
    第七章
    第六章
    第五章
    第四章
    第三章
    第二章
    第一章
  • 原文地址:https://www.cnblogs.com/New-Godess/p/4348900.html
Copyright © 2011-2022 走看看